イテレータパターンの実装と応用

イテレータパターン(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 文による簡潔な走査が可能である。ただし、イテレータパターンの背後にある「内部構造の隠蔽」と「走査ロジックの分離」という設計思想を理解することは、柔軟なコレクション設計において依然として重要である。

タグ: C# デザインパターン イテレータパターン IEnumerable IEnumerator

6月22日 19:40 投稿