Iterator Pattern – parcurgerea colecțiilor fără expunerea internelor

  • Doru Bulubasa
  • 19 December 2025

În dezvoltarea aplicațiilor apare frecvent nevoia de a parcurge colecții de obiecte: liste, arbori, agregate sau structuri personalizate. De multe ori, implementarea internă a acestor colecții nu ar trebui expusă către exterior. Iterator Pattern rezolvă exact această problemă, oferind o metodă standard de parcurgere, fără a dezvălui detalii interne.

Iterator Pattern este un design pattern comportamental, extrem de des întâlnit în .NET, chiar dacă nu este mereu recunoscut ca atare.


Ce este Iterator Pattern?

Iterator Pattern oferă o interfață care permite accesarea secvențială a elementelor unei colecții, fără a expune structura sa internă.

Ideea de bază este simplă:

„Separă logica de parcurgere de structura colecției.”

Astfel, clientul nu trebuie să știe dacă parcurge o listă, un array, un arbore sau o structură custom.


De ce este important?

Fără Iterator Pattern:

  • Codul client ajunge să depindă de implementarea colecției

  • Parcurgerea diferitelor structuri devine inconsistentă

  • Orice modificare internă rupe codul existent

Cu Iterator Pattern:

  • Colecția își păstrează încapsularea

  • Parcurgerea devine uniformă

  • Codul este mai curat și mai ușor de testat


Structura pattern-ului

Iterator Pattern include următoarele componente:

  1. Iterator – definește metodele de parcurgere

  2. ConcreteIterator – implementează efectiv parcurgerea

  3. Aggregate – interfața colecției

  4. ConcreteAggregate – implementarea colecției

În .NET, aceste concepte sunt deja bine reprezentate prin IEnumerable și IEnumerator.


Iterator Pattern în .NET – exemplul clasic

Cel mai cunoscut exemplu de Iterator Pattern în .NET este:

foreach (var item in collection)
{
    // folosim item
}

În spate:

  • collection implementează IEnumerable

  • foreach folosește IEnumerator

  • structura internă rămâne ascunsă


Exemplu practic – Iterator custom în C#

1️⃣ Colecția

public class ProductCollection
{
    private readonly List<string> _products = new();

    public void Add(string product)
    {
        _products.Add(product);
    }

    public IEnumerator<string> GetEnumerator()
    {
        return _products.GetEnumerator();
    }
}

Această colecție:

  • ascunde lista internă

  • expune doar mecanismul de parcurgere


2️⃣ Utilizarea iteratorului

var products = new ProductCollection();
products.Add("Laptop");
products.Add("Mouse");
products.Add("Keyboard");

foreach (var product in products)
{
    Console.WriteLine(product);
}

✔ Codul client nu știe nimic despre List<string>

✔ Parcurgerea este sigură și controlată


Iterator cu yield return

C# simplifică enorm implementarea iteratorilor prin yield return:

public IEnumerable<int> GetEvenNumbers(int max)
{
    for (int i = 0; i <= max; i++)
    {
        if (i % 2 == 0)
            yield return i;
    }
}

Acest cod:

  • creează automat un iterator

  • este lazy (execută la nevoie)

  • consumă mai puțină memorie


Când este util Iterator Pattern?

✔ când ai colecții complexe

✔ când vrei să eviți expunerea internelor

✔ când ai mai multe moduri de parcurgere

✔ când vrei iterație lazy

✔ când vrei cod ușor de testat


Avantaje

✅ Separare clară a responsabilităților

✅ Încapsulare mai bună

✅ Cod client simplu

✅ Suport nativ în .NET

✅ Lazy evaluation


Dezavantaje

⚠️ Overhead pentru colecții foarte simple

⚠️ Complexitate mai mare pentru structuri triviale

În practică, beneficiile depășesc aproape întotdeauna dezavantajele.


Iterator Pattern vs LINQ

LINQ folosește masiv Iterator Pattern:

  • Where

  • Select

  • OrderBy

  • Take

Toate sunt implementate ca iteratori lazy, ceea ce explică performanța și flexibilitatea lor.


Concluzie

Iterator Pattern este unul dintre cele mai importante și mai folosite design patterns în .NET. Chiar dacă nu îl implementezi manual zilnic, îl folosești constant prin foreach, IEnumerable și LINQ.

Înțelegerea acestui pattern te ajută să:

  • scrii cod mai curat

  • eviți dependențe inutile

  • creezi colecții extensibile și robuste

Scrie un comentariu

Adresa de mail nu va fi publicata. Campurile obligatorii sunt marcate cu *