CSharp:Design Pattern Iterator
From Aino Wiki
Contents
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:
Codice
Segue la struttura della solution adottata come esempio
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
Parole chiave: