イテレータパターン(Iterator Pattern)は、コレクション内部の構造を隠蔽しつつ、その要素を順番に走査するための共通インターフェースを提供するデザインパターンである。
このパターンが有効な主なケースは以下の通りである:
- コレクションの内部表現を公開せずに要素にアクセスしたい場合
- 同じコレクションに対して複数の走査方法をサポートしたい場合
- 異なる種類のコレクションに対しても統一された走査インターフェースを提供したい場合
カスタムイテレータの実装例(C#)
abstract class IIterator
{
public abstract object GetFirst();
public abstract object GetNext();
public abstract bool HasNext();
public abstract object GetCurrent();
}
class NameIterator : IIterator
{
private readonly NameCollection _collection;
private int _index = 0;
public NameIterator(NameCollection collection)
{
_collection = collection;
}
public override object GetFirst()
{
_index = 0;
return _collection[_index];
}
public override object GetNext()
{
if (HasNext())
{
_index++;
return _collection[_index];
}
return null;
}
public override bool HasNext()
{
return _index < _collection.Size - 1;
}
public override object GetCurrent()
{
return _collection[_index];
}
}
abstract class IAggregate
{
public abstract IIterator CreateIterator();
}
class NameCollection : IAggregate
{
private readonly List<object> _items = new();
public override IIterator CreateIterator()
{
return new NameIterator(this);
}
public int Size => _items.Count;
public object this[int index]
{
get => _items[index];
set => _items.Add(value);
}
}
クライアントコード
static void RunIteratorDemo()
{
var names = new NameCollection();
names[0] = "Alice";
names[1] = "Bob";
names[2] = "Charlie";
var iterator = names.CreateIterator();
iterator.GetFirst();
while (iterator.HasNext())
{
Console.WriteLine($"{iterator.GetCurrent()} が退出しました");
iterator.GetNext();
}
Console.WriteLine($"{iterator.GetCurrent()} が退出しました");
}
現代の C# では IEnumerable および IEnumerator インターフェースが標準で提供されており、foreach 文による簡潔な走査が可能である。ただし、イテレータパターンの背後にある「内部構造の隠蔽」と「走査ロジックの分離」という設計思想を理解することは、柔軟なコレクション設計において依然として重要である。