0% completed
Iterator Pattern provides a way to access elements of a collection object sequentially without exposing its underlying structure. This pattern introduces the concept of iterator. iterator is a tool through which you can traverse a collection (arrays, lists, or even more complex data structures) in a standardized manner.
Consider a scenario when you are working with a complex data structure, such as a graph or a tree. Extracting the data from such data structure is tricky, especially if don't want to show the internal structure of the data structure to the client. Without the use of an iterator pattern, the code to navigate through the elements will be complex and tightly coupled.
Suppose you have a library of books and want to display the titles of all the books. If you don't have an iterator pattern, you will be required to know how books are stored in the library. This will lead to an inefficient code that will be difficult to maintain.
This is elegantly solved by the Iterator pattern, which separates the traversal mechanism from the data structure itself. It involves two key players: the 'Iterable' that provides the iterator and the 'Iterator' that encapsulates the traversal logic.
The image above shows how we create an iterator for the library using the Iterator pattern so that external code can iterate through the books without having to know how they are internally stored. To traverse the collection, the iterator provides functions like hasNext()
and next()
.
In the image, you can see a music player application on smartphone. There are 'next' and 'previous' buttons on the phone's screen in addition to a list of songs. This arrangement represents how the Iterator pattern is used to move through the playlist.
Like an iterator in programming lets you iterate through items in a collection, users can easily navigate through their music playlist in this real-world scenario, mirroring the Iterator pattern. The application's "next" and "previous" buttons function as the next() and previous() methods of an iterator's real-world equivalents, offering a straightforward and user-friendly method of accessing songs in the desired order. This illustration shows how the idea of iterators is present in both software development and regular user experiences.
next()
to get the next element in the sequence and hasNext()
to see if there is another element.Let's consider a book collection in a library. We want to provide a way to iterate through the books without exposing the underlying data structure of the collection.
// Iterator Interface interface Iterator { hasNext(): Boolean next(): Object } // Concrete Iterator for Book Collection class BookIterator implements Iterator { private currentIndex = 0 private collection: BookCollection BookIterator(BookCollection collection) { this.collection = collection } hasNext(): Boolean { return currentIndex < collection.getLength() } next(): Object { if (this.hasNext()) { book = collection.getAt(currentIndex) currentIndex += 1 return book } return null } } // Aggregate Interface interface Aggregate { createIterator(): Iterator } // Concrete Aggregate for Books class BookCollection implements Aggregate { private books: Array BookCollection() { books = new Array() } addBook(book: Book) { books.append(book) } getLength(): Integer { return books.length } getAt(index: Integer): Book { return books[index] } createIterator(): Iterator { return new BookIterator(this) } } // Client Code main() { bookCollection = new BookCollection() bookCollection.addBook(new Book("Book 1")) bookCollection.addBook(new Book("Book 2")) // Add more books... iterator = bookCollection.createIterator() while (iterator.hasNext()) { book = iterator.next() print(book.title) } }
hasNext()
and next()
methods. It provides a method of sequentially accessing elements within a collection without disclosing the collection's underlying structure.createIterator()
.BookIterator
for iterating through them.Let's look at the implementation of this example in multiple programming languages.
BookCollection
class uses Python's native iteration capabilities. The __iter__
method returns an iterator over the books
list. This simplifies the code significantly compared to languages without built-in iteration features.BookCollection
class implements the iterable protocol by defining the [Symbol.iterator]()
method. This method returns an iterator object with a next
function that conforms to the iterator protocol, allowing the collection to be iterated over with a for...of
the loop.Pros | Cons |
---|---|
Separation of Concerns: Separates the collection's internal structure and the algorithm to traverse it. | Complexity: Can add extra complexity and overhead to simple collections. |
Flexibility: Provides multiple ways to traverse a collection (forward, backward, filtered). | Iterator Invalidation: Iterators can become invalid if the collection is modified during iteration. |
Abstraction and Consistency: Provides a uniform interface for multiple types of collections. | Concurrent Modification: Standard iterators typically don't support safe concurrent modification and iteration. |
Control over Iteration: Gives more control over the pace and order of traversal. | Statefulness: Iterators maintain state, which needs careful handling to avoid errors. |
Memory Efficiency: Efficient in memory usage, especially for large collections. | Simplicity vs. Overhead: For simple tasks, using an iterator might be more complex than necessary. |
The Iterator pattern is a fundamental design pattern that is especially useful in scenarios that require a standardized way to access collection elements. Though it adds more levels of abstraction, making the codebase more structured and manageable, it's vital to take into account the possible overheads and complications it may cause.
.....
.....
.....