1. パターンの意図
イテレータ(Iterator)パターン は、
集合体(コレクション)の要素に順次アクセスする方法を提供し、内部構造を隠す デザインパターンです。
解決する問題
- 配列・リスト・ツリーなど、データ構造ごとにアクセス方法が違うとクライアントが複雑になる
- 内部実装を隠しつつ「次の要素を取る」仕組みを統一したい
- コレクションを横断するコードを再利用しやすくしたい
ポイント
- Iterator:要素に順にアクセスするインターフェース
- ConcreteIterator:実際の走査処理を実装
- Aggregate(集合体):要素を保持するインターフェース
- ConcreteAggregate:コレクションの実装、Iterator を返す
2. UML 図
3. Flutter / Dart 実装例
Iterator インターフェース
abstract class Iterator<T> {
bool hasNext();
T next();
}
Aggregate(集合体)
abstract class Aggregate<T> {
Iterator<T> createIterator();
}
実装
class NumberIterator implements Iterator<int> {
final List<int> _numbers;
int _index = 0;
NumberIterator(this._numbers);
@override
bool hasNext() => _index < _numbers.length;
@override
int next() => _numbers[_index++];
}
class NumberCollection implements Aggregate<int> {
final List<int> _numbers;
NumberCollection(this._numbers);
@override
Iterator<int> createIterator() => NumberIterator(_numbers);
}
利用例
void main() {
var collection = NumberCollection([1, 2, 3, 4, 5]);
var it = collection.createIterator();
while (it.hasNext()) {
print(it.next());
}
}
出力:
1
2
3
4
5
4. Android / Kotlin 実装例
Iterator
interface Iterator<T> {
fun hasNext(): Boolean
fun next(): T
}
Aggregate
interface Aggregate<T> {
fun createIterator(): Iterator<T>
}
実装
class NumberIterator(private val numbers: List<Int>) : Iterator<Int> {
private var index = 0
override fun hasNext(): Boolean = index < numbers.size
override fun next(): Int = numbers[index++]
}
class NumberCollection(private val numbers: List<Int>) : Aggregate<Int> {
override fun createIterator(): Iterator<Int> = NumberIterator(numbers)
}
利用例
fun main() {
val collection = NumberCollection(listOf(1, 2, 3, 4, 5))
val it = collection.createIterator()
while (it.hasNext()) {
println(it.next())
}
}
5. 実務ユースケース
Flutter
- Widget ツリーを走査(再帰構造を隠す)
- 独自コレクション(Graph, Tree)を外部公開する際の共通アクセス手段
- データセットを順に UI に流す
Android / Kotlin
- Kotlin の
Iterator
/Iterable
標準機能(for-each ループ) - Cursor API(DB結果の走査)
- RecyclerView.Adapter でデータを順に取り出す処理
6. メリット / デメリット
メリット
- コレクションの内部構造を隠蔽できる
- 走査処理を統一し、再利用しやすい
- 複数の走査アルゴリズム(前方向 / 逆方向 / 条件付き)を切り替え可能
デメリット
- クラス数が増える
- 単純な配列アクセスには不要(言語の標準 Iterator で十分)
まとめ
- Iterator パターンは「集合体の内部構造を隠して、統一的に走査する仕組み」
- Flutter/Android では 標準 Iterator に慣れているので意識する機会は少ないが、
独自データ構造(Tree/Graph)を走査するときに有効