Iterator Pattern
Abstract away the iteration over a collection of items.
The Iterator Pattern is used basically when you have a collection of items you wish to iterate over, but don't exactly know how the collection has been implemented as (is it a list ? is it a stack ? etc).
Thus, we simply abstract away the logic of iteration to an interface and make sure that the user's of this interface are exposed to the same set of methods for iteration, irrespective of what our collection is implemented as
Analogy....
Think of the interface as your TV remote and the methods as the buttons. No matter what circuitry logic is implemented under the hood, inside the remote, you (the user of this interface) simply need to know that which button does what and it does it !
CODE | ANALOGY | FUNCTION |
---|---|---|
Interface(aka iterator) | TV remote |
Exposes the logic in the form of easy to use methods |
IteratorTypes | Wiring inside the TV remote |
Classes extending the interface and containing implementation logic |
Methods | Buttons on TV remote |
Called by the user and implemented under the hood by iterator types |
Caretaker | User of TV remote |
Just uses the methods |
Eg : Browser history, depending on your browser may either be stored as a List of Strings or an Array (implemented as a stack) of strings
Thus, every time the implementation of the collection is changed, we just need to create a new Iterator Type which will handle the under-the-hood-logic of this new implementation of our collection, so users can again easily iterate over it
Resources
The source code for all prominent design patterns has been properly implemented and documented in this GitHub repostitory by me.
Project Description
Here, in this article, we will be building a simple collection of browser history URLs implemented differently (as a list and as a stack) and their corresponding iterators for handling the same
Implementing the Caretaker
Performs the state management
Type | Name | Function |
---|---|---|
Methods | push( ) |
Add a new item to the collection |
pop( ) |
Remove the last item from the collection | |
createIterator( ) |
Creates an object of the Iterator (interface) and of whatever IteratorType (child class extending the interface), to iterate over the current implementation of the collection of items |
Implementing the Iterator
An interface with child classes that expose the basic methods required to iterate over a collection, whilst abstracting away the iteration logic
Type | Name | Function |
---|---|---|
Methods | hasNext( ) |
Returns a boolean that specifies whether we've reached the end of the collection |
current( ) |
Returns an item of the collection | |
next( ) |
Increments iteration counter |
Implementing the IteratorType classes
Child classes that extend the Iterator interface
Each such class contains all the iteration logic over a particular implementation of the collection (eg : List, Stack) but abstracts away all this logic, serving up only 3 methods, as enliseted by the Iterator interface.
Using this pattern in our application
Import all the necessary classes and modules into main.java for a final showdown of our application ! I have used the BrowseHistoryForArray.java implementation here but you can go forward and try out the List implementation (BrowseHistoryForList.java) as well.
var iteratorHistory = new BrowseHistory();
iteratorHistory.push("a");
iteratorHistory.push("b");
iteratorHistory.push("c");
Iterator iterator = iteratorHistory.createIterator();
while(iterator.hasNext()){
System.out.println(iterator.current());
iterator.next();
}
What basically happens when the implmentation of collection changes :
- push( ), pop( ) methods in Caretaker are redefined as per new implementation
- createIterator( ) returns a different IteratorType, (if not existent, makes such a IteratorType) which knows how to iterator over this implementation of the collection.
- All changes in code are confined only to the CareTaker, and if required, IteratorType class, instead of dependent classes.
Conclusion
Congrats on unlocked the secret of how the most complex iterations are made simple by workings under the hood. You should feel pretty comfortable now developing the next level iteration functionalities in your applications. Until next time...
References..
Whatever I have learnt and implemented here in code as well as the explanation is all from the teachings of the brilliant Mosh Hamedani and his course on Design Patterns which I would recommend you to take if you are really interested in exploring the beauty of Object Oriented Programming