lunes, 4 de mayo de 2015

Iterator

Iterator

Propósito

Proveer una forma de tener acceso secuencial a los elementos de un objeto agregado sin tener que exponer su representación interna.

También conocido como: Cursor

Motivación


Un objeto agregado, tal como una lista, debería proveer un modo de brindar acceso a sus elementos sin exponer su estructura interna. Más aún, quizás se desea recorrer la lista en diferentes formas, dependiendo de lo que Ud. quiera realizar. Pero, probablemente, la idea no es aumentar la interfaz de la lista con operaciones para recorridos diferentes, aún anticipando los que se necesitarán. Tal vez, también se necesite tener más de un recorrido en la misma lista.
El patrón Iterator permite llenar todas estas expectativas. La idea principal en este patrón es tomar la responsabilidad del acceso y recorrido de la lista y colocarla dentro del objeto iterator. La clase Iterator define una interfaz para el acceso de los elementos de la lista. Un objeto iterador es responsable de mantener la pista del elemento actual; esto es, sabe cuáles elementos ya han sido recorridos.


Aplicabilidad


Usamos el patrón Iterator:

  • Para tener acceso a los contenidos de un objeto agregado sin tener que exponer su estructura interna.
  • Para soportar múltiples recorridos de objetos agregados.
  • Para proveer una interfaz uniforme para recorridos en estructuras diferentes de agregados (esto es, para soportar iteración polimorfa).
Estructura



Participantes
  • Iterator: el cual define una interfaz para el acceso y recorrido de los elementos.
  • ConcreteIterator: el cual implementa la interfaz de Iterator y mantiene la pista de la posición actual en el recorrido del agregado.
  • Aggregate: el cual define una interfaz para la creación de un objeto Iterator.
  • ConcreteAggregate: el cual implementa la interfaz de creación de Iterator para retornar una instancia del ConcreteIterator adecuado.
Colaboraciones


Un ConcreteIterator mantiene la pista de cuál es el objeto actual en el agregado y puede calcular el objeto siguiente en el recorrido.




Consecuencias


Este patrón tiene tres consecuencias importantes:

  1. Soporte a variaciones en el recorrido de un agregado,puesto que agregados complejos pueden requerir recorridos en muchas formas. Los iteradores hacen fácil cambiar el algoritmo de recorrido, con sólo reemplazar la instancia del iterador a una diferente.
  2. Los iteradores simplifican la interfaz de los agregados, ya que la interfaz de los recorridos se encuentra en los iteradores y no en los agregados.
  3. Más de un recorrido puede estar pendiente en un agregado, puesto que cada iterador mantiene la pista de su recorrido. Por lo tanto, se puede tener más de un recorrido en progreso al tiempo.
Implementación

Los iteradores tienen muchas variantes en la implementación y alternativas. Algunas de las más importantes son las siguientes. Las ventajas dependen de las estructuras de control que el lenguaje provea.
  • ¿Quién controla la iteración?. Referido a iteración interna (controlada por el iterador), o iteración externa (controlada por el cliente).
  • ¿Quién define el algoritmo de recorrido?. Referido a si lo define el agregado, con lo cual el iterador es utilizado sólo como cursor de la posición actual; o si lo define el iterador.
  • ¿Cuán robusto es el iterador?. Referido a la manera en que se aseguran las iteraciones cuándo se ha realizado un cambio (inserción y/o eliminación) en el objeto agregado.
  • Operaciones adicionales en el iterador. Referido a la adición de operaciones a las ya básicas (First, Next, IsDone y CurrentItem).
  • Utilización de iteradores polimorfos en C++.
  • Iteradores con acceso privilegiado. Referido a que un iterador puede ser visto como una extensión (friend) del agregado que lo creó.
  • Iteradores para compuestos (Composite).
  • Iteradores nulos. Referido a un iterador útil para el manejo de condiciones de frontera.
Código de ejemplo

public interface Iterator { 
     public void first();
     public void next(); 
     public boolean isDone(); 
     public Object currentItem(); 
}

public interface Aggregate { 
public Iterator createIterator(); 
public Object get(int); 
public int count(); 

public class ListIterator { 
private Aggregate a; 
private int current; 
ListIterator (Aggregate a); { 
this.a = a; 
current = 0; 
public void first() { current = 0; } 
public void next() { current++; } 
public boolean isDone() { return current >= a.count(); } 
public Object currentItem() { return a.get(current); } 
}

Usos conocidos


Los Iteradores son comunes en sistemas orientados a objetos (Smalltalk, ET++, ObjectWindows, etc.), de hecho, la mayoría de librerías de clases ofrecen iteradores en una forma u otra.
En general, los iteradores se ofrecen junto con las estructuras de datos básicas: Listas, Colas, Pilas, etc.

Patrones relacionados
  • Iteradores se aplican a menudo en estructuras recursivas comoComposites.
  • Iteradores poliformicos se basan en Factory Menthods para instanciar la subclase Iterator apropiada.
  • Memento se utiliza a menudo en colaboración con el patrón Iterator. Un Iterator puede unas un Memento para capturar el estado de una iteración.
Referencias
  • Design Patterns Elements of Reusable Object-Oriented Software, GoF.
  • http://kybele.escet.urjc.es/documentos/SI/Patrones/13_Iterator.ppt
  • http://sistemas.unitecnologica.edu.co/ebooks/Programacion/Java/Documentos/Java%205%20Certifications/Programing/API/Iterator.pdf

No hay comentarios:

Publicar un comentario