Iterator Design Pattern is one of the patterns that are used in collections to traversal the objects(Looping). Iterator Design Pattern provides a way to access and traverse items sequentially without exposing their underlying representation.
Every programming language has data structures to store groups of objects. The main objective of the Iterator Design Pattern is to access the collection of objects without exposing the internal structure.
Consider there is a collection of objects in a structure(Ex: In Java Collections) and clients want to iterate or traverse between the objects. In those situations, the ideal way is to use an iterator to find the object or loop the whole collection.
There are four participants in Iterator Design Pattern. Those are
- Iterator Interface: Define the methods to traverse between objects
- Concrete Iterator class: Implementation of methods in an interface. This will provide a way to store objects and get the state of each.
- Aggregate Interface: Collection class which defines iterator for client
- Concrete Aggregate Class: Return a real iterator for external use by implementing an aggregate interface.
Client class is an iterating loop of objects. That means patterns help clients loop their objects.
Let’s take a real-world simple example of iterating objects using an iterator design pattern.
Iterator Design Pattern Real World Example
Consider in Hospital OPD or in channel centers, there are patients waiting in a queue according to the appointments. A doctor gives treatments to patients, but the hospital provides a way to sequence the patients according to appointment number. Once a doctor arrives, then loop the patient’s queue by hospital nurses just like an iterator.
In this scenario, doctors expose patients to investigate their health. However the hospital plans patients in a sequential manner. Let’s move into a class diagram of this scenario and then move into the implementation.
Iterator Design Pattern in Java
Let’s implement the above diagram. The client iterates patients sequentially.
// Main object use to create seaquence class Patients { private String name; private String appoinmentNo; public Patients(String name, String appoinmentNo) { this.name = name; this.appoinmentNo = appoinmentNo; } public String getName() { return name; } public String getAppoinmentNo() { return appoinmentNo; } } //Definition of iterator behaviours interface Iterator<E> { // To get the next element(Patient ) E next(); // To retrieve the current element (Patient ) E currentItem(); // To check whether there is any next element (Patient ) or not. boolean hasNext(); } // Implements the Iterator with common behaviours class PatientIterator implements Iterator<Patients> { private Patients[] patients; private int position; public PatientIterator(Patients[] patients) { this.patients = patients; position = 0; } @Override public Patients next() { return patients[position++]; } @Override public Patients currentItem() { return patients[position]; } @Override public boolean hasNext() { if(position >= patients.length) return false; return true; } } //Define the iterator fro client interface List<E> { Iterator<E> iterator(); } // Create Patient iterator by implementing iterator class PatientList implements List<Patients> { private Patients[] patients; public PatientList(Patients[] patients) { this.patients = patients; } @Override public Iterator<Patients> iterator() { return new PatientIterator(patients); } } // Client class use the iterator public class IteraterPatientDemo { public static void main(String[] args){ Patients[] ps = new Patients[4]; ps[0] = new Patients("John","01"); ps[1] = new Patients("Kain","02"); ps[2] = new Patients("Dan","03"); ps[3] = new Patients("Ann","04"); List<Patients> list = new PatientList(ps); Iterator<Patients> iterator = list.iterator(); while(iterator.hasNext()) { Patients currentPatient = iterator.next(); System.out.println("Appoinment No: "+currentPatient.getAppoinmentNo() +" is "+currentPatient.getName()); } } }
Output
Appoinment No: 01 is John Appoinment No: 02 is Kain Appoinment No: 03 is Dan Appoinment No: 04 is Ann
Advantages of Iterator Design Pattern
- Traversal with a list of objects without affecting loop objects.
- Easy to create different types of iterators by extending (Inheritance).
- Do not need to know the size of the list.
Iterator Pattern Usage
As you know this is for returning a list of item/s as a sequence and recognizable by behavioral methods sequentially returning instances of a different type from a queue. Patterns heavily used for reverse through the list and supported by Java using the below packages.
- Iterable interface
- All implementations of java.util.Iterator
- All implementations of java.util.Enumeration
Design Patterns Book
Design Patterns are one of the most famous solutions in programming and millions of people follow them to fix their tasks, design projects, and so on. Most of the patterns are created based on basic OOP concepts (If your beginner then read our basic OOP, Encapsulation, Inheritance, Polymorphism, and Abstraction articles with great examples )
There are a lot of articles and design pattern books available with different examples to read. Other than our article if you are interested in this topic you could go through the below books as well.
Books | Description |
---|---|
Head First Design Patterns: A Brain-Friendly Guide | My favorite and it’s more readable. There are good examples and they look good to beginners as well. |
Design Patterns: Elements of Reusable Object-Oriented Software | There are 23 design patterns. showing how to select an appropriate pattern for your case. |
Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software | There are a lot of simple examples showing how to use design patterns in the correct way. Those are based on SOLIC principles. |
There are a lot of design pattern ebooks on Amazon. Those design patterns are written with great examples in a different programming language. I included a few of them according to their best ranking.