Patrón de iterador

Iterator Pattern es un patrón de diseño relativamente simple y de uso frecuente. Hay muchas estructuras/colecciones de datos disponibles en todos los idiomas. Cada colección debe proporcionar un iterador que le permita iterar a través de sus objetos. Sin embargo, al hacerlo, debe asegurarse de no exponer su implementación. Supongamos que estamos construyendo una aplicación que requiere que mantengamos una lista de notificaciones. Eventualmente, alguna parte de su código requerirá iterar sobre todas las notificaciones. Si implementáramos su colección de notificaciones como una array, las iteraría como:

// If a simple array is used to store notifications
for (int i = 0; i < notificationList.length; i++)
     Notification notification = notificationList[i]);
// If ArrayList is Java is used, then we would iterate
// over them as:
for (int i = 0; i < notificationList.size(); i++)
    Notification notification = (Notification)notificationList.get(i);

Y si se tratara de alguna otra colección como conjunto, árbol, etc., la forma de iterar cambiaría ligeramente. Ahora, ¿qué pasa si construimos un iterador que proporciona una forma genérica de iterar sobre una colección independientemente de su tipo?

// Create an iterator
Iterator iterator = notificationList.createIterator();

// It wouldn’t matter if list is Array or ArrayList or
// anything else.
while (iterator.hasNext())
{
    Notification notification = iterator.next());
}

El patrón de iterador nos permite hacer precisamente eso. Formalmente, se define de la siguiente manera: el patrón de iterador proporciona una forma de acceder a los elementos de un objeto agregado sin exponer su representación subyacente. Diagrama de clase: Aquí tenemos una interfaz común Agregado para el cliente, ya que la desvincula de la implementación de su colección de objetos. ConcreteAggregate implementa createIterator() que devuelve un iterador para su colección. La responsabilidad de cada ConcreteAggregate es instanciar un ConcreteIterator que pueda iterar sobre su colección de objetos. La interfaz del iterador proporciona un conjunto de métodos para atravesar o modificar la colección que, además de next()/hasNext(), también puede proporcionar funciones para buscar, eliminar, etc. Entendamos esto a través de un ejemplo. Supongamos que estamos creando una barra de notificaciones en nuestra aplicación que muestra todas las notificaciones que se encuentran en una colección de notificaciones. NotificationCollection proporciona un iterador para iterar sobre sus elementos sin exponer cómo ha implementado la colección (array en este caso) al Cliente (NotificationBar). El diagrama de clases sería:A continuación se muestra la implementación de Java de la misma: 

Java

// A Java program to demonstrate implementation
// of iterator pattern with the example of
// notifications
 
// A simple Notification class
class Notification
{
    // To store notification message
    String notification;
 
    public Notification(String notification)
    {
        this.notification = notification;
    }
    public String getNotification()
    {
        return notification;
    }
}
 
// Collection interface
interface Collection
{
    public Iterator createIterator();
}
 
// Collection of notifications
class NotificationCollection implements Collection
{
    static final int MAX_ITEMS = 6;
    int numberOfItems = 0;
    Notification[] notificationList;
 
    public NotificationCollection()
    {
        notificationList = new Notification[MAX_ITEMS];
 
        // Let us add some dummy notifications
        addItem("Notification 1");
        addItem("Notification 2");
        addItem("Notification 3");
    }
 
    public void addItem(String str)
    {
        Notification notification = new Notification(str);
        if (numberOfItems >= MAX_ITEMS)
            System.err.println("Full");
        else
        {
            notificationList[numberOfItems] = notification;
            numberOfItems = numberOfItems + 1;
        }
    }
 
    public Iterator createIterator()
    {
        return new NotificationIterator(notificationList);
    }
}
 
// We could also use Java.Util.Iterator
interface Iterator
{
    // indicates whether there are more elements to
    // iterate over
    boolean hasNext();
 
    // returns the next element
    Object next();
}
 
// Notification iterator
class NotificationIterator implements Iterator
{
    Notification[] notificationList;
 
    // maintains curr pos of iterator over the array
    int pos = 0;
 
    // Constructor takes the array of notificationList are
    // going to iterate over.
    public  NotificationIterator (Notification[] notificationList)
    {
        this.notificationList = notificationList;
    }
 
    public Object next()
    {
        // return next element in the array and increment pos
        Notification notification =  notificationList[pos];
        pos += 1;
        return notification;
    }
 
    public boolean hasNext()
    {
        if (pos >= notificationList.length ||
            notificationList[pos] == null)
            return false;
        else
            return true;
    }
}
 
// Contains collection of notifications as an object of
// NotificationCollection
class NotificationBar
{
    NotificationCollection notifications;
 
    public NotificationBar(NotificationCollection notifications)
    {
        this.notifications = notifications;
    }
 
    public void printNotifications()
    {
        Iterator iterator = notifications.createIterator();
        System.out.println("-------NOTIFICATION BAR------------");
        while (iterator.hasNext())
        {
            Notification n = (Notification)iterator.next();
            System.out.println(n.getNotification());
        }
    }
}
 
// Driver class
class Main
{
    public static void main(String args[])
    {
        NotificationCollection nc = new NotificationCollection();
        NotificationBar nb = new NotificationBar(nc);
        nb.printNotifications();
    }
}

Producción:

-------NOTIFICATION BAR------------
Notification 1
Notification 2
Notification 3

Tenga en cuenta que si hubiéramos usado ArrayList en lugar de Array, no habrá ningún cambio en el código del cliente (barra de notificación) debido al desacoplamiento logrado por el uso de la interfaz del iterador. Lectura adicional: método de iterador en referencias de Python: patrones de diseño Head First

Este artículo es una contribución de Sulabh Kumar. Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *