Login Login
MORE

WIDGETS

Widgets

Wanted articles
Who is online?
Article tools

CSharp:Design Pattern Iterator

From Aino Wiki

Jump to: navigation, search

Introduzione

Appartenente alla classe dei pattern comportamentali.

L'Iterator risolve diversi problemi connessi all'accesso e alla navigazione attraverso gli elementi, in particolare, di una struttura dati contenitrice, senza necessità di conoscere i dettagli dell'implementazione e della sua struttura interna. L'oggetto principale su cui si basa questo design pattern è l'iteratore.

In parole semplici, fornisce un modo di accedere ed iterare su una collezione di elementi nello stesso modo senza conoscerne il tipo (sia esso un array, un dizionario, una lista etc).

Esempio

Esempio preso dal corso di Design Pattern seguito su Lynda.com (LinkedIn)
Si suppone di dover compiere delle azioni su liste di giornalisti presenti su diverse città, queste liste possono essere di varia natura (array, Lista, dizionario etc) ma su ciascuna vanno eseguite le stesse azioni da qui la necessità di iterare astraendo dalla tipologia di ciascuna lista.

Diagramma delle classi del Pattern:

Iterator pattern Diagramma delle classi.png

Codice

Segue la struttura della solution adottata come esempio

DesignPatterns - Iterator Solution 01.png

Nella cartella "Aggregate" c'è il DAL ed il Modello mentre nella cartella Iterator, c'è il pattern vero e proprio che definisce i metodi comuni per l'accesso al Modello ovvero alle informazioni.

Classi dell'Aggregate

Il questa cartella si definiscono le classi contenitore delle informazioni che come premesso sono raccolte in strutture differenti ma lo scopo di queste classi è quello di fornire un wrapper per l'algoritmo dell'iterazione.

Segue la classe di interfaccia che definisce il contratto per le due classi concrete che seguono. In INewspaper.cs

namespace Iterator.Aggregate
{
    // Aggregate
    public interface INewspaper
    {
        IIterator CreateIterator();
    }
}

Primo aggregato di informazioni nella prima classe concreta, la struttura usata è l'ARRAY
in LAPaper.cs

namespace Iterator.Aggregate
{
    // ConcreteAggregate
    public class LAPaper : INewspaper
    {        
        private string[] _reporters;
        public LAPaper()
        {
            _reporters = new[] { "Ronald Smith - LA",
                                 "Danny Glover - LA",
                                 "Yolanda Adams - LA",
                                 "Jerry Straight - LA",
                                 "Rhonda Lime - LA",
                                };
        }
 
        public IIterator CreateIterator()
        {
            return new LAPaperIterator(_reporters);
        }
    }
}

Altra classe concreta, la struttura usata è la 'LISTA
NYPaper.cs

namespace Iterator.Aggregate
{
    // ConcreteAggregate
    public class NYPaper : INewspaper
    {        
        private List<string> _reporters;
        public NYPaper()
        {
            _reporters = new List<string>
                        {"John Mesh - NY",
                         "Susanna Lee - NY",
                         "Paul Randy - NY",
                         "Kim Fields - NY",
                         "Sky Taylor - NY"
                        };            
        }
 
        public IIterator CreateIterator()
        {
            return new NYPaperIterator(_reporters); 
        }
    }
}

Classi dell'Iterator

Qui ci son le classi che implementeranno l'algoritmo di iterazione che come anticipato, avranno sostanzialmente 4 metodi, il modo migliore per definire questo comportamento\struttura comune è con l'interfaccia come nella seguente classe: in IIterator.cs

namespace Iterator.Iterator
{
    // Iterator
    public interface IIterator
    {
        void First();           //  Sets current element to the first element
        string Next();          //  Advances current to next element
        bool IsDone();          //  Check if end of collection
        string CurrentItem();   //  returns the current element
    }
}

Prima classe concreta in LAPaperIterator.cs, questa come la successiva, sono gli unici posti dove è necessario conoscere la struttura con cui son esposte le informazioni, mentre i metodi esposti son comuni. Quest'ultimo aspetto ci consentirà di astrarre dalla struttura dei dati e mettere a fattor comune il comportamento, e lo si vedrà nella classe in Program.cs.

namespace Iterator.Iterator
{
    public class LAPaperIterator : IIterator
    {
        private string[] _reporters;
        private int _current;
 
        public LAPaperIterator(string[] _reporters)
        {
            this._reporters = _reporters;
            _current = 0;
        }
        public string CurrentItem()
        {
            return _reporters[_current];
        }
 
        public void First()
        {
            _current = 0;
        }
 
        public bool IsDone()
        {
            return _current >= _reporters.Length;
        }
 
        public string Next()
        {
            return _reporters[_current++];
        }
    }
}

in NYPaperIterator.cs

namespace Iterator.Iterator
{
    public class NYPaperIterator : IIterator
    {
        private List<string> _reporters;
        private int _current;
 
        public NYPaperIterator(List<string> _reporters)
        {
            this._reporters = _reporters;
            _current = 0;
        }
 
        public string CurrentItem()
        {
            return _reporters.ElementAt(_current);
        }
 
        public void First()
        {
            _current = 0;
        }
 
        public bool IsDone()
        {
            return _current >= _reporters.Count;
        }
 
        public string Next()
        {
            return _reporters.ElementAt(_current++);
        }
    }
}

Main

Segue il program.cs, è qui che si astrae dalla reale struttura delle informazioni, il metodo con l'algortmo per il loro trattamento è semplicemente nel metodo 'PrintReporters'.

namespace Iterator
{
    class Program
    {
        static void Main(string[] args)
        {
            INewspaper nyt = new NYPaper();
            INewspaper lat = new LAPaper();
 
            IIterator nypIterator = nyt.CreateIterator();
            IIterator lapIterator = lat.CreateIterator();
 
            Console.WriteLine("--------   NYPaper");
            PrintReporters(nypIterator);
 
            Console.WriteLine("--------   LAPaper");
            PrintReporters(lapIterator);
 
            Console.ReadLine();
        }
 
        static void PrintReporters(IIterator iterator) {
            iterator.First();
            while(!iterator.IsDone()){
                Console.WriteLine(iterator.Next());
            }
        }
    }
}

Mappa e Link


C# | Design Pattern | Teoria


Visual Studio


Parole chiave:

Author