05 Dec 2023



Intermediate

The Iterator design pattern is a behavioral pattern that provides a way to access elements of a collection sequentially without exposing the underlying details of the collection. In C#, the Iterator pattern typically involves the following main components:

  1. Iterator Interface:

    • Declares the interface for an iterator, which includes methods like Next, HasNext, and possibly others depending on the requirements.
    public interface IIterator<T>
    {
        T Next();
        bool HasNext();
    }
    
  2. Aggregate Interface:

    • Declares the interface for the collection of elements.
    • Includes a method to create an iterator.
    public interface IAggregate<T>
    {
        IIterator<T> CreateIterator();
    }
    
  3. Concrete Iterator:

    • Implements the IIterator interface.
    • Keeps track of the current position in the collection.
    • Provides methods to traverse the collection.
    public class ConcreteIterator<T> : IIterator<T>
    {
        private readonly List<T> collection;
        private int index = 0;
    
        public ConcreteIterator(List<T> collection)
        {
            this.collection = collection;
        }
    
        public T Next()
        {
            T item = collection[index];
            index++;
            return item;
        }
    
        public bool HasNext()
        {
            return index < collection.Count;
        }
    }
    
  4. Concrete Aggregate:

    • Implements the IAggregate interface.
    • Creates an instance of the appropriate iterator for the collection.
    public class ConcreteAggregate<T> : IAggregate<T>
    {
        private List<T> collection = new List<T>();
    
        public IIterator<T> CreateIterator()
        {
            return new ConcreteIterator<T>(collection);
        }
    
        public void AddItem(T item)
        {
            collection.Add(item);
        }
    }
    
  5. Client:

    • Uses the iterator to traverse the collection without knowing its internal structure.
    class Client
    {
        static void Main()
        {
            ConcreteAggregate<string> aggregate = new ConcreteAggregate<string>();
            aggregate.AddItem("Item 1");
            aggregate.AddItem("Item 2");
            aggregate.AddItem("Item 3");
    
            IIterator<string> iterator = aggregate.CreateIterator();
    
            while (iterator.HasNext())
            {
                string item = iterator.Next();
                Console.WriteLine(item);
            }
        }
    }
    

In this example:

  • IIterator is the interface for the iterator, providing methods to traverse the collection.
  • IAggregate is the interface for the collection of elements, including a method to create an iterator.
  • ConcreteIterator is a concrete implementation of the iterator that keeps track of the current position in the collection and provides methods to traverse it.
  • ConcreteAggregate is a concrete implementation of the aggregate that creates an instance of the appropriate iterator for the collection.
  • The Client creates an instance of the concrete aggregate, adds items to it, and uses the iterator to traverse the collection without knowing its internal structure.

The Iterator pattern separates the traversal logic from the actual collection, providing a consistent interface for accessing elements of different types of collections. It promotes the principle of encapsulation and allows clients to iterate over a collection without exposing its implementation details.

software-design-patterns
iterator-design-pattern
c#