Behavioral Design Patterns provide solution for the better interaction between objects and how to provide lose coupling and flexibility to extend easily. Following design patterns come under this category.
Iterator pattern presents a way to access the elements of an object without exposing the underlying presentation.
Iterator pattern is one of the behavioral pattern and it’s used to provide a standard way to traverse through a group of Objects.
Iterator pattern is widely used in java collection framework where Iterator
interface provides methods for traversing through a collection.
The logic for iteration is embedded in the collection itself and it helps client program to iterate over them easily. Iterator pattern is not only about traversing through a collection; we can provide different kind of iterators based on our requirements. Iterator pattern hides the actual implementation of traversal through the collection and client programs just use iterator
methods. An Iterator object contains public methods to allow a client object to navigate through the list of objects within the container.
Iterator
interface and keeps track of the current position in the traversal of the aggregate.Iterator
object.Iterator
interface to return an instance of the proper ConcreteIterator
.When to use the Iterator design pattern
Java
Let's look at an example of this. We have an Item
class, which represents an item on a menu. An item has a name and a price.
File Item.java.
public class Item { String name; float price; public Item(String name, float price) { this.name = name; this.price = price; } public String toString() { return name + ": $" + price; } }
Here is the Menu
class. It has a list of menu items of type Item. Items can be added via the addItem()
method. The iterator()
method returns an iterator of menu items. The MenuIterator
class is an inner class of Menu
that implements the Iterator
interface for Item
objects. It contains basic implementations of the hasNext()
, next()
, and remove()
methods.
File Menu.java.
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Menu { List- menuItems; public Menu() { menuItems = new ArrayList<Item>(); } public void addItem(Item item) { menuItems.add(item); } public Iterator<Item> iterator() { return new MenuIterator(); } class MenuIterator implements Iterator<Item> { int currentIndex = 0; @Override public boolean hasNext() { if (currentIndex >= menuItems.size()) { return false; } else { return true; } } @Override public Item next() { return menuItems.get(currentIndex++); } @Override public void remove() { menuItems.remove(--currentIndex); } } }
The Demo
class demonstrates the iterator pattern. It creates three items and adds them to the menu object. Next, it gets an Item
iterator from the menu object and iterates over the items in the menu. After this, it calls remove()
to remove the last item obtained by the iterator. Following this, it gets a new iterator object from the menu and once again iterates over the menu items.
File Demo.java.
import java.util.Iterator; public class Demo { public static void main(String[] args) { Item i1 = new Item("spaghetti", 7.50f); Item i2 = new Item("hamburger", 6.00f); Item i3 = new Item("chicken sandwich", 6.50f); Menu menu = new Menu(); menu.addItem(i1); menu.addItem(i2); menu.addItem(i3); System.out.println("Displaying Menu:"); Iterator<Item> iterator = menu.iterator(); while (iterator.hasNext()) { Item item = iterator.next(); System.out.println(item); } System.out.println("\nRemoving last item returned"); iterator.remove(); System.out.println("\nDisplaying Menu:"); iterator = menu.iterator(); while (iterator.hasNext()) { Item item = iterator.next(); System.out.println(item); } } }
Python 3
import abc class Item: def __init__(self, name, price): self.name = name self.price = price def __str__(self): return "{}: $ {}".format(self.name, self.price) class MenuIterator: def __init__(self, items): self.indx = 0 self.items = items def has_next(self): return False if self.indx >= len(self.items) else True def next(self): item = self.items[self.indx] self.indx += 1 return item def remove(self): return self.items.pop() class Menu: def __init__(self): self.items = [] def add(self, item): self.items.append(item) def iterator(self): return MenuIterator(self.items) if __name__ == '__main__': i1 = Item("spaghetti", 7.50) i2 = Item("hamburger", 6.00) i3 = Item("chicken sandwich", 6.50) menu = Menu() menu.add(i1) menu.add(i2) menu.add(i3) print("Displaying Menu:") iterator = menu.iterator() while iterator.has_next(): item = iterator.next() print(item) print("Removing last item returned") iterator.remove() print("Displaying Menu:") iterator = menu.iterator() while iterator.has_next(): item = iterator.next() print(item)