Skip to main content

[Design Pattern] 행동 패턴 9. 이터레이터 (Iterator)




이터레이터 (Iterator) #

이터레이터

  • 내부 세부구조를 노출하지 않고, 어떤 집합 객체에 속한 요소들을 순차적으로 접근할 수 있는 방법을 제공한다.



개념적인 예시 #

// 이터레이터 
abstract class Iterator : IEnumerator
{
    object IEnumerator.Current => Current();

    public abstract int Key();
    public abstract object Current();
    public abstract bool MoveNext();
    public abstract void Reset();
}

class AlphabeticalOrderIterator : Iterator
{
    // 해당 컬렉션 
    private WordsCollection _collection;
    
    // 현재 위치 
    private int _position = -1;
    
    private bool _reverse = false;

    public AlphabeticalOrderIterator(WordsCollection collection, bool reverse = false)
    {
        this._collection = collection;
        this._reverse = reverse;

        if (reverse)
        {
            this._position = collection.getItems().Count;
        }
    }
    
    public override object Current()
    {
        return this._collection.getItems()[_position];
    }

    public override int Key()
    {
        return this._position;
    }
    
    public override bool MoveNext()
    {
        int updatedPosition = this._position + (this._reverse ? -1 : 1);

        if (updatedPosition >= 0 && updatedPosition < this._collection.getItems().Count)
        {
            this._position = updatedPosition;
            return true;
        }
        else
        {
            return false;
        }
    }
    
    public override void Reset()
    {
        this._position = this._reverse ? this._collection.getItems().Count - 1 : 0;
    }
}

// 이터레이터로 순회할 컬렉션 
abstract class IteratorAggregate : IEnumerable
{
    public abstract IEnumerator GetEnumerator();
}

class WordsCollection : IteratorAggregate
{
    List<string> _collection = new List<string>();
    
    bool _direction = false;
    
    public void ReverseDirection()
    {
        _direction = !_direction;
    }
    
    public List<string> getItems()
    {
        return _collection;
    }
    
    public void AddItem(string item)
    {
        this._collection.Add(item);
    }
    
    public override IEnumerator GetEnumerator()
    {
        // 이터레이터를 생성한다. (팩토리 메서드)
        return new AlphabeticalOrderIterator(this, _direction);
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 컬렉션 
        var collection = new WordsCollection();
        collection.AddItem("First");
        collection.AddItem("Second");
        collection.AddItem("Third");

        // Straight traversal
        foreach (var element in collection)
        {
            Console.WriteLine(element);
        }

        // Reverse traversal
        collection.ReverseDirection();

        foreach (var element in collection)
        {
            Console.WriteLine(element);
        }
    }
}



References #