Patrón Iterator

Download Report

Transcript Patrón Iterator

Patrón Iterator
Santiago García Sánchez
Rebeca Marcos Salcedo
Mª Cristina Zapatero Gironda
Iterator
Pertenece a la categoría de patrones
de comportamiento la cual tiene que
ver con el modo en que las clases y
objetos interactúan y se reparten
responsabilidades.
También es conocido como
Cursor.
Propósito
Este patrón proporciona un modo de
acceder a los elementos de un
agregado sin mostrar su estructura
interna.
Motivación
El patrón Iterator define una interfaz
mediante la cual se ofrece un acceso
secuencial a un agregado.
Un agregado se puede recorrer de
diferentes modos y además permite
realizar varios recorridos de forma
simultánea.
Motivación
Es posible definir iteradores con
diferentes políticas de recorrido sin
necesidad de enumerarlos en el
agregado.
Ya que el cliente se ajusta a una
interfaz determinada se pueden
implementar subclases de iteradores
con la misma interfaz para lograr
iteradores polimórficos.
Motivación
Cada objeto agregado concreto se encarga de
crear sus propios iteradores mediante un
método factoría. De este modo el cliente, para
obtener un iterador válido, solo necesita
solicitarlo al agregado.
Siguiendo este enfoque se crean dos jerarquías
de clases, una para los agregados y otra para
los iteradores.
Aplicabilidad
El patrón Iterator se usa para:
acceder al contenido de un objeto agregado sin
exponer su representación interna.
permitir varios recorridos sobre objetos
agregados.
proporcionar una interfaz uniforme para
recorrer diferentes estructuras agregadas
(iteración polimórfica).
Estructura
Participantes
Iterador: Define una interfaz para recorrer los
agregados.
IteradorConcreto: Implementa la interfaz
Iterador.
Agregado: Define la interfaz para crear un
objeto iterador.
AgregadoConcreto: Implementa la interfaz de
creación de un iterador para devolver un
IteradorConcreto
Colaboraciones
Un IteradorConcreto almacena la
posición del objeto actual en el
agregado de modo que sabe cual es
el objeto siguiente en el recorrido.
Consecuencias
Permite variaciones en el recorrido de un
agregado.
Los iteradores simplifican la interfaz
Agregado.
Se puede hacer mas de un recorrido a la
vez sobre un agregado.
Implementación
Hay dos modos de implementar los iteradores:
externos e internos. En los externos el cliente es el
que controla el avance del recorrido mientras que
en los internos el recorrido se hace de manera
automática.
El algoritmo de recorrido puede estar en el
agregado, guardando en el iterador solo el índice
del objeto actual (el iterador sería un cursor), o
puede estar en el iterador siendo mas sencillo
recorrer el agregado de diferentes formas.
Implementación
Un iterador robusto garantiza que las
inserciones y borrados no interferirán con
el recorrido y lo hace sin copiar el
agregado. La mayoría se basan en
registrar el iterador con el agregado.
Implementación
Se pueden definir en la interfaz Iterador
operaciones adicionales para aumentar su
funcionalidad, como por ejemplo anterior
(posiciona el iterador en el elemento
anterior), e irA (posiciona el iterador en
un objeto que cumpla el criterio
especificado).
Implementación
Cuando se recorre un árbol es útil tener
un IteradorNulo. El iterador pide
recursivamente los iteradores a sus nodos
hijos hasta que se alcanzan los nodos hoja
que devuelven el IteradorNulo cuya
condición de haTerminado se evalúa
siempre a verdadero.
Código de Ejemplo
public interface Iterator{
public void primero();
public void siguiente();
public boolean haTerminado();
public Object elementoActual();
}
Código de Ejemplo
public interface Agregado{
Iterator crearIterador();
int tamaño();
Object get(int index);
void add(Object object);
void remove(int index);
}
Código de Ejemplo
public class IteradorLista implements Iterator{
private Agregado agregado;
private int actual;
IteradorLista (Agregado agregado){
this.agregado = agregado;
actual = 0;
}
public void primero(){
actual = 0;
}
public void siguiente(){
actual = actual + 1;
}
public boolean haTerminado(){
return actual >= agregado.tamaño();
}
public Object actual (){
return agregado.get(actual);
}
}
Ejemplo
Ejemplo