Iterator Pattern

Iterator Pattern

Iterator pattern is very commonly used design pattern in Java and .Net programming environment. This pattern is used to get a way to access the elements of a collection object in sequential manner without any need to know its underlying representation.

The Iterator pattern is also known as Cursor.
In collection framework, we are now using Iterator that is preferred over Enumeration.

java.util.Iterator interface uses Iterator Design Pattern.

Advantage of Iterator Pattern

  • It supports variations in the traversal of a collection.
  • It simplifies the interface to the collection.

Usage of Iterator Pattern:

It is used:

  • When you want to access a collection of objects without exposing its internal representation.
  • When there are multiple traversals of objects need to be supported in the collection.

Let’s understand this through an example. Suppose we are creating a notification bar in our application that displays all the notifications which are held in a notification collection. NotificationCollection provides an iterator to iterate over its elements without exposing how it has implemented the collection (array in this case) to the Client (NotificationBar).
 
The class diagram would be:
Below is the Java implementation of the same:

// 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 notifiactionList 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();
    }
}
Output:
-------NOTIFICATION BAR------------
Notification 1
Notification 2
Notification 3
Notice that if we would have used ArrayList instead of Array there will not be any change in the client (notification bar) code due to the decoupling achieved by the use of iterator interface.

Comments

Popular posts from this blog

gsutil Vs Storage Transfer Service Vs Transfer Appliance

SQL basic interview question