🧩 Iterator パターン
✅ 設計意図
- 集合体の要素を順番にアクセスする方法を提供し、内部構造を隠蔽
God Object
の中でデータ構造が肥大化しており、ループ処理がベタ書きされている場合に有効
✅ 適用理由
- 内部データ(リスト、ツリーなど)に対する走査を一貫した方法で提供
- 外部から簡潔かつ安全に要素を扱えるようになる
✅ 向いているシーン
- カスタムデータ構造をループ処理する必要がある場面
for
やwhile
文が重複・分散しており、走査ロジックが一貫していない場合
✅ コード例
- 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())
✅ 解説
このコードは Iterator パターン を使用して、コレクション(UserCollection
)内の要素を順番にアクセスする方法を提供している。
Iterator
パターンは、コレクションの内部構造を隠蔽しつつ、要素を順次操作できるようにするデザインパターン。
1. Iterator パターンの概要
- Iterator: コレクション内の要素を順次操作するためのインターフェースを定義
- このコードでは
Iterator<T>
が該当
- このコードでは
- IterableCollection: イテレーターを生成するためのインターフェースを定義
- このコードでは
IterableCollection<T>
が該当
- このコードでは
- ConcreteCollection: コレクションを具体的に実装し、イテレーターを生成する
- このコードでは
UserCollection
が該当
- このコードでは
2. 主なクラスとその役割
Iterator<T>
- イテレーターのインターフェース
hasNext
メソッドで次の要素が存在するかを確認し、next
メソッドで次の要素を取得する
IterableCollection<T>
- イテレーターを生成するためのインターフェース
createIterator
メソッドを定義
UserCollection
- コレクションを具体的に実装したクラス
- 内部にユーザー名(
string
)の配列を保持し、add
メソッドで要素を追加 createIterator
メソッドでイテレーターを生成
3. UML クラス図
4. Iterator パターンの利点
- 内部構造の隠蔽: コレクションの内部構造を隠しつつ、要素にアクセス可能
- 統一的な操作: コレクションの種類に依存せず、同じインターフェースで操作できる
- 拡張性: 新しいコレクションを追加する場合も、
Iterator
とIterableCollection
を実装するだけで対応可能
この設計は、コレクションの要素を順次操作する際に内部構造を意識せずに扱えるようにする。特に複雑なデータ構造を扱う場合に有効。