イテレーターパターン
イテレーターパターン(Iterator Pattern) は、コレクション(リストや配列など)の要素に順番にアクセスする方法を提供するデザインパターンです。このパターンでは、コレクションの内部構造を隠蔽しながら、その要素に対して繰り返し処理を行うための一貫した方法を提供します。
イテレーターパターンを使うことで、クライアントコードはコレクションの要素を操作する際に、その具体的なデータ構造に依存することなく繰り返し処理を実行できるようになります。これにより、内部構造を意識せずにコレクションを遍歴することが可能になります。
TypeScriptでのイテレーターパターンの実装
以下に、TypeScriptでイテレーターパターンを実装する例を紹介します。この例では、自分で定義したコレクション(文字列のコレクション)をイテレータで扱うシンプルなシナリオを取り上げます。
文字列コレクションの例
typescript
// イテレータインターフェース
interface Iterator<T> {
next(): T | null;
hasNext(): boolean;
}
// コレクションインターフェース
interface IterableCollection<T> {
createIterator(): Iterator<T>;
}
// 具体的なイテレータクラス
class StringIterator implements Iterator<string> {
private collection: StringCollection;
private position: number = 0;
constructor(collection: StringCollection) {
this.collection = collection;
}
next(): string | null {
if (this.hasNext()) {
return this.collection.getItems()[this.position++];
}
return null;
}
hasNext(): boolean {
return this.position < this.collection.getItems().length;
}
}
// 具体的なコレクションクラス
class StringCollection implements IterableCollection<string> {
private items: string[] = [];
addItem(item: string): void {
this.items.push(item);
}
getItems(): string[] {
return this.items;
}
createIterator(): Iterator<string> {
return new StringIterator(this);
}
}
// 実際の使用例
const collection = new StringCollection();
collection.addItem('Apple');
collection.addItem('Banana');
collection.addItem('Cherry');
const iterator = collection.createIterator();
while (iterator.hasNext()) {
console.log(iterator.next());
}
解説
Iteratorインターフェース
Iterator<T>
インターフェースは、コレクションの要素に順次アクセスするためのnext
メソッドと、次の要素が存在するかどうかを確認するhasNext
メソッドを定義しています。
IterableCollectionインターフェース
IterableCollection<T>
インターフェースは、コレクションに対してイテレータを作成するためのcreateIterator
メソッドを定義しています。このインターフェースを実装することで、任意のコレクションに対してイテレータを提供することができます。
StringIteratorクラス(具体的なイテレータ)
StringIterator
クラスは、Iterator
インターフェースを実装し、StringCollection
内の要素にアクセスする役割を持ちます。next
メソッドで次の要素を返し、hasNext
メソッドでまだ要素が残っているかを確認します。
StringCollectionクラス(具体的なコレクション)
StringCollection
クラスは、文字列のコレクションを管理するクラスで、IterableCollection
インターフェースを実装しています。createIterator
メソッドを使用して、コレクションに対するイテレータを生成します。
実際の使用例
StringCollection
にいくつかのアイテムを追加し、createIterator
メソッドでイテレータを作成します。while
ループを使って、イテレータを使ってコレクション内のアイテムを順番に表示しています。
利点
- 内部構造の隠蔽: コレクションの内部構造をクライアントに隠蔽しながら、コレクションを操作することができます。
- 一貫したインターフェース: コレクションの種類に関係なく、一貫したインターフェースで要素にアクセスできるため、コードの柔軟性が向上します。
- 複数のイテレータ: 同じコレクションに対して複数のイテレータを同時に使用することが可能です。これにより、異なるループ条件でコレクションを遍歴することができます。
使用例
- コレクション遍歴: リスト、セット、ツリーなどのコレクションを遍歴する際に、イテレータを使うことで簡潔に要素にアクセスできます。
- データベースのレコード操作: データベースから取得したレコードに対して、順次アクセスして処理する場合にもイテレータが使われます。
- GUIコンポーネントの管理: GUIアプリケーションで複数のコンポーネントを順次操作する際に、イテレータパターンが有効です。
まとめ
イテレータパターンは、コレクション内の要素に順次アクセスするための統一された方法を提供するデザインパターンです。TypeScriptでの実装を通じて、コレクションの内部構造に依存せずに要素にアクセスする仕組みを理解することができました。
このパターンを活用することで、さまざまなコレクションに対して柔軟にアクセスでき、コードの再利用性と可読性を高めることが可能です。