|
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 espectativas. 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.
Separar el mecanismo de recorrido del objeto List nos permite definir
iteradores para diferentes políticas de recorrido sin tener que
enumerarlas en la interfaz de List. Por ejemplo, FilteringListIterator
puede proveer acceso solo a aquellos elementos que cumplan una política
de filtro específica.
Note que el iterador y la lista están acoplados, y el cliente
debe saber que es una lista lo que se está recorriendo, en lugar
de algún otra estructura agregada. De ahí que el cliente
comprometa una estructura agregada particular. Sería mejor si pudiésemos
cambiar la clase agregada sin cambiar el código cliente. Esto lo
logramos generalizando el concepto de iterador para soportar iteración
polimorfa.
Definimos una clase AbstractList que provea una interfaz común
para manipular listas. De igual forma, necesitamos una clase abstracta
Iterator que defina una interfaz de iteración común. Luego
podemos definir subclasses iteradoras concretas para las diferentes implementaciones
de la lista. Como resultado, el mecanismo de iteración llega a ser
independiente de las clases agregadas concretas.
El problema restante radica en cómo crear el iterador. Ya que
lo que queremos es escribir código independiente de las subclasses
concretas de List, no podemos simplemente instanciar una clase específica.
En su lugar, hacemos a los objetos de la lista responsables por la creación
de su iterador correspondiente. Esto requiere una operación tal
como CreateIterator, por medio de la cual los clientes solicitan un objeto
iterador. |