π§© Iterator Pattern
β Intentβ
- Provide a way to access elements of a collection sequentially without exposing its underlying structure
- Useful when a
God Object
contains a complex data structure with hardcoded loop logic
β Motivationβ
- To offer a consistent way to traverse internal data structures (lists, trees, etc.)
- Allows elements to be handled safely and concisely from the outside
β When to Useβ
- When looping over custom data structures is required
- When
for
orwhile
loops are scattered and duplicated, and traversal logic lacks consistency
β Code Exampleβ
- TypeScript
- PHP
- Python
interface Iterator<T> {
hasNext(): boolean;
next(): T;
}
interface IterableCollection<T> {
createIterator(): Iterator<T>;
}
class UserCollection implements IterableCollection<string> {
private users: string[] = [];
add(user: string) {
this.users.push(user);
}
createIterator(): Iterator<string> {
let index = 0;
const users = this.users;
return {
hasNext() {
return index < users.length;
},
next() {
return users[index++];
},
} as Iterator<string>;
}
}
// ε©η¨δΎ
const users = new UserCollection();
users.add("Hiroshi");
users.add("Satoshi");
const it = users.createIterator();
while (it.hasNext()) {
console.log(it.next());
}
<?php
interface IteratorInterface {
public function hasNext(): bool;
public function next(): string;
}
interface IterableCollection {
public function createIterator(): IteratorInterface;
}
class UserCollection implements IterableCollection {
private array $users = [];
public function add(string $user): void {
$this->users[] = $user;
}
public function createIterator(): IteratorInterface {
return new UserIterator($this->users);
}
}
class UserIterator implements IteratorInterface {
private int $index = 0;
public function __construct(private array $users) {}
public function hasNext(): bool {
return $this->index < count($this->users);
}
public function next(): string {
return $this->users[$this->index++];
}
}
// ε©η¨δΎ
$users = new UserCollection();
$users->add("Hiroshi");
$users->add("Satoshi");
$it = $users->createIterator();
while ($it->hasNext()) {
echo $it->next() . PHP_EOL;
}
from abc import ABC, abstractmethod
class IteratorInterface(ABC):
@abstractmethod
def has_next(self) -> bool:
pass
@abstractmethod
def next(self) -> str:
pass
class IterableCollection(ABC):
@abstractmethod
def create_iterator(self) -> IteratorInterface:
pass
class UserCollection(IterableCollection):
def __init__(self):
self.users: list[str] = []
def add(self, user: str):
self.users.append(user)
def create_iterator(self) -> IteratorInterface:
return UserIterator(self.users)
class UserIterator(IteratorInterface):
def __init__(self, users: list[str]):
self.users = users
self.index = 0
def has_next(self) -> bool:
return self.index < len(self.users)
def next(self) -> str:
user = self.users[self.index]
self.index += 1
return user
# ε©η¨δΎ
users = UserCollection()
users.add("Hiroshi")
users.add("Satoshi")
it = users.create_iterator()
while it.has_next():
print(it.next())
β Explanationβ
This code applies the Iterator
pattern to provide a way to access elements within a collection (UserCollection
) in sequence.
The Iterator
pattern allows elements of a collection to be accessed one at a time, while hiding the internal structure of the collection.
1. Overview of the Iterator Patternβ
-
Iterator: Defines an interface for accessing elements sequentially
- In this code, represented by
Iterator<T>
- In this code, represented by
-
IterableCollection: Defines an interface for creating iterators
- In this code, represented by
IterableCollection<T>
- In this code, represented by
-
ConcreteCollection: Implements the collection and provides a concrete iterator
- In this code, represented by
UserCollection
- In this code, represented by
2. Key Classes and Their Rolesβ
-
Iterator<T>
- The interface for iterators
hasNext
checks for the existence of the next elementnext
retrieves the next element
-
IterableCollection<T>
- Interface for collections that can produce iterators
- Declares the
createIterator
method
-
UserCollection
- A concrete collection class
- Maintains an internal list of usernames (
string
) - Provides an
add
method to insert elements - Implements the
createIterator
method to return an iterator
3. UML Class Diagramβ
4. Benefits of the Iterator Patternβ
- Encapsulation of Internal Structure: Allows access to elements without revealing the internal organization of the collection
- Consistent Operations: Enables uniform access to different types of collections through a common interface
- Extensibility: New collections can be added by implementing
Iterator
andIterableCollection
This design enables safe and consistent traversal of collection elements without needing to understand the internal structureβespecially useful when dealing with complex data models.