Iterator es un patrón de diseño de comportamiento que permite el recorrido secuencial por una estructura de datos compleja sin exponer sus detalles internos.
Gracias al patrón Iterator, los clientes pueden recorrer elementos de colecciones diferentes de un modo similar, utilizando una única interfaz iteradora.
Complejidad:
Popularidad:
Ejemplos de uso: El patrón es muy común en el código C#. Muchos frameworks y bibliotecas lo utilizan para proporcionar una forma estandarizada de recorrer sus colecciones.
Identificación: El patrón Iterator es fácil de reconocer por sus métodos de navegación (como next
, previous
y otros). El código cliente que utiliza iteradores puede no tener acceso directo a la colección recorrida.
Ejemplo conceptual
Este ejemplo ilustra la estructura del patrón de diseño Iterator . Se centra en responder las siguientes preguntas:
¿De qué clases se compone?
¿Qué papeles juegan esas clases?
¿De qué forma se relacionan los elementos del patrón?
Program.cs: Ejemplo conceptual
using System;
using System.Collections;
using System.Collections.Generic;
namespace RefactoringGuru.DesignPatterns.Iterator.Conceptual
{
abstract class Iterator : IEnumerator
{
object IEnumerator.Current => Current();
// Returns the key of the current element
public abstract int Key();
// Returns the current element
public abstract object Current();
// Move forward to next element
public abstract bool MoveNext();
// Rewinds the Iterator to the first element
public abstract void Reset();
}
abstract class IteratorAggregate : IEnumerable
{
// Returns an Iterator or another IteratorAggregate for the implementing
// object.
public abstract IEnumerator GetEnumerator();
}
// Concrete Iterators implement various traversal algorithms. These classes
// store the current traversal position at all times.
class AlphabeticalOrderIterator : Iterator
{
private WordsCollection _collection;
// Stores the current traversal position. An iterator may have a lot of
// other fields for storing iteration state, especially when it is
// supposed to work with a particular kind of collection.
private int _position = -1;
private bool _reverse = false;
public AlphabeticalOrderIterator(WordsCollection collection, bool reverse = false)
{
this._collection = collection;
this._reverse = reverse;
if (reverse)
{
this._position = collection.getItems().Count;
}
}
public override object Current()
{
return this._collection.getItems()[_position];
}
public override int Key()
{
return this._position;
}
public override bool MoveNext()
{
int updatedPosition = this._position + (this._reverse ? -1 : 1);
if (updatedPosition >= 0 && updatedPosition < this._collection.getItems().Count)
{
this._position = updatedPosition;
return true;
}
else
{
return false;
}
}
public override void Reset()
{
this._position = this._reverse ? this._collection.getItems().Count - 1 : 0;
}
}
// Concrete Collections provide one or several methods for retrieving fresh
// iterator instances, compatible with the collection class.
class WordsCollection : IteratorAggregate
{
List<string> _collection = new List<string>();
bool _direction = false;
public void ReverseDirection()
{
_direction = !_direction;
}
public List<string> getItems()
{
return _collection;
}
public void AddItem(string item)
{
this._collection.Add(item);
}
public override IEnumerator GetEnumerator()
{
return new AlphabeticalOrderIterator(this, _direction);
}
}
class Program
{
static void Main(string[] args)
{
// The client code may or may not know about the Concrete Iterator
// or Collection classes, depending on the level of indirection you
// want to keep in your program.
var collection = new WordsCollection();
collection.AddItem("First");
collection.AddItem("Second");
collection.AddItem("Third");
Console.WriteLine("Straight traversal:");
foreach (var element in collection)
{
Console.WriteLine(element);
}
Console.WriteLine("\nReverse traversal:");
collection.ReverseDirection();
foreach (var element in collection)
{
Console.WriteLine(element);
}
}
}
}
Output.txt: Resultado de la ejecución
Straight traversal:
First
Second
Third
Reverse traversal:
Third
Second
First
Iterator en otros lenguajes