Iterator Design Pattern
Overview
The Iterator Pattern is a basic and widely used design pattern. Each language has a large number of data collections as well as structures. Iterator is known to be a behavioral design pattern that allows you to traverse components of a set without revealing the representation underneath (for example: stack, lists, tree, etc.).
Assume we are developing an application that needs us to keep track of a collection of alerts. Some of your code will eventually need iterating through all alerts.
Let's discuss the participants in the Iterator Design Pattern.
The Iterator Pattern's participants are given below:
1) Iterator: It is defined as the method for accessing or traversing the elements list. It is responsible for providing methods that concrete iterators need to follow as well as implement.
2) ConcreteIterator: Iterator interface functions are implemented by 'ConcreteIterator'. It is a class responsible for maintaining a track of the present location in the aggregate collection traverse.
3) Aggregate: The fourth design participant is the aggregate which is defined as a collection interface that offers a function for creating an Iterator object.
4) ConcreteAggregate: It is the last required participant which takes care of the implementation of the Aggregate interface. ConcreteAggregate's particular method yields a ConcreteIterator object.
When Will We Need Iterator Design Pattern?
Each and every software programming language has data structures such as lists and maps that would be used to hold a set of associated elements. In the programming language Java, users have many interfaces like List, Map, Sets as well as various implementations like HashMaps and ArrayLists.
A collection can be useful if it grants access to its components while not disclosing its inner structure. That's the job of the iterators.
So, whenever we have a number of objects and when users want a mechanism to loop through each collection piece in a specific order, we should utilize the iterator pattern to construct the solution.
It is utilized to navigate through a container as well as access its elements. Algorithms and containers are separated using the iterator pattern.
Let's suppose we want to develop a new data structure which is a collection, we can then use the iterator pattern. If someone wants to use the data structure, they can simply use the iterators you describe rather than having to create a unique iterator in their code.
How Does Iterator Design Pattern Work?
When your collection has a complicated data structure under the hood that you wish to hide from clients, then we use the concept of the Iterator pattern. We generally use this pattern either for our convenience.
The iterator design is responsible to encapsulate(hide) the complexities of dealing with a complicated data structure and provides the client with a number of straightforward ways for retrieving collection members. While this method is incredibly handy for the client, it also safeguards the collection from negligent activities that the client may take if he or she worked directly with the collection.
Structure of Iterator Design Pattern
The UML diagram below shows all the participants present in the Iterator Design Pattern. All these participants form the structure of this particular pattern.
Implementation of Iterator Design Pattern
Let's go through the steps of how we can implement the Iterator Design Pattern:
- The first step that a user needs to do is to define the interface for iterators. This should contain a function for retrieving the next item out of a collection. However, you may add a few more functions, like getting the preceding item, monitoring the current location, as well as confirming the ending of the loop.
- The second step is to define your collection interface as well as explain how to retrieve iterators. The return type is just as same as its iterator interface. If we intend to just have numerous separate groups of iterators, one could specify equivalent functions.
- The third step is to create concrete iterator classes for the sets you want to use iterators to traverse. A singular collection instance must be linked to an iterator object. To create the link with the iterator objects we make use of the iterator’s constructor.
- Within your collection class, define the collection interface. The fundamental concept is to give the customer convenience for building iterators that are suited to a certain collection class. To make a connection among these, a collection object should send it to the iterator's constructor.
- The last step is to examine the application code as well as change every collection traversing logic using iterators. Any time the customer or the user wants to traverse through the collection items, it retrieves a separate iterator instance.
Pseudocode
Java
Let's understand how to use Iterator Design Pattern in Java and write a program to add items in a cart.
The first step is to create an Iterator interface.
Python
Let's make an application that adds items to a cart using Python programming language.
C++
We are going to implement the same mini-application whose objective is "Add the products in a cart and iterate on them" in C++ programming language.
First of all let's create our custom class for Products
So when our class for Product is written, we can proceed to create a container Cart to store the Products and the Iterater to access the products of cart.
After the definition of these classes we can use them in our main function, below is an example to illustrate the concept through code.
Output:
Real Life Examples
-
You intend to spend a couple of days in Rome and see all of the city's major attractions to visit. However, once there, you may spend a significant amount of time roaming in loops, unable to locate even the Colosseum located in the city.
-
You may, on the other side, get a digital tour application for your cellphone as well as utilize it for navigating to various places. It's clever as well as cheap, and you could spend as much time as you want in some intriguing areas.
-
A third possibility is to invest some of your trip cash on hiring a local tour who is aware of the city and would help you travel with ease. The host would be able to personalize the trip to your preferences, show you all of the attractions, and tell you a lot of intriguing stories. That will be much more fun, but also more costly.
All of these options—random routes in your brain, smartphone navigation, or a personal guide—act as iterators across Rome's immense collection of sites and attractions.
Pros and Cons of Iterator Design Pattern
Every situation has its pros and cons, and so does the Iterator design pattern.
Let's know when to utilize this design pattern and when not to. In other words, let's discuss what are the trade-offs of utilizing this pattern.
Pros of Iterator Design Pattern
- The concept of single responsibility. By separating cumbersome traversal methods into different classes, you may clean up the client code as well as collections.
- The concept of open/closed - The programmer can introduce additional kinds of collections as well as iterators to the code which already exists without affecting anything.
- Since each iterator object has its own iteration state, you may loop over the similar collection concurrently.
- Now for the exact cause you can keep delaying an iteration and then resume it later if necessary.
Cons of Iterator Design Pattern
- If your software simply interacts with basic collections, using the Iterator Design pattern may be an overkill in that case.
- Explicitly traversing items of some specialized collections may be more competent than using an iterator design pattern.
Difference Between Iterator Design Pattern and Template Method Design Pattern
Iterator Design Pattern | Template Method Design Pattern |
---|---|
The Iterator Pattern captures the process of iterating through a group of objects. | The template method design pattern belongs to the behavioral design pattern category. It refers to a method that is implemented as a skeleton of functions. |
Difference Between Iterator Design Pattern and Proxy Pattern
Iterator Design Pattern | Proxy Pattern |
---|---|
This technique is used to gain a method to sequentially access the components of a collection object without having to know its fundamental structure. | A class in the proxy pattern represents the functionality of some other class. |
The iterator pattern is a type of behavioral pattern. | This design pattern is classified as a structural pattern. |
Frequently Asked Questions
Question 1) What are the major benefits of using the iterator design pattern?
Answer) Because the iterator follows the Single Responsibility and Open/Closed SOLID principles, the code is easy for use, understanding, and testing. This Single Responsibility Principle helps us to tidy up the traversal algorithms' client as well as collections.
Question 2) What do design patterns teach us?
Answer) Design patterns are defined as a collection of tried-and-true answers to typical program design issues. Recognizing patterns is valuable even if you never run into these issues since it teaches you how to address a plethora of issues using object-oriented design concepts.
Question 3) What is the design pattern for the iterator?
Answer) The iterator pattern is one of the widely used design patterns in the programming language Java as well as other programming languages. This technique is used to gain a method to sequentially access the components of a collection object without having to know its underlying form. The iterator pattern is known to be a type of behavioral pattern.