State Pattern – schimbarea comportamentului în funcție de stare

  • Doru Bulubasa
  • 16 January 2026

În aplicațiile reale, obiectele rareori au un comportament fix. De cele mai multe ori, modul în care reacționează depinde de starea internă în care se află. De exemplu:

  • o comandă poate fi Nouă, Procesată, Livrată sau Anulată

  • un document poate fi Draft, Publicat sau Arhivat

  • un utilizator poate fi Activ, Suspendat sau Blocat

O abordare naivă ar presupune folosirea multor if / switch în cod, ceea ce duce rapid la:

  • cod greu de citit

  • încălcarea principiului Open/Closed

  • dificultăți mari la adăugarea de noi stări

State Pattern rezolvă elegant această problemă.


Ce este State Pattern?

State Pattern permite unui obiect să-și schimbe comportamentul atunci când starea internă se modifică. Obiectul va părea că și-a schimbat clasa.

Ideea principală este:

  • fiecare stare este reprezentată printr-o clasă separată

  • comportamentul specific stării este mutat în acea clasă

  • obiectul principal (contextul) delegă comportamentul către starea curentă


Problema: comportament dependent de stare

Să luăm un exemplu simplu: o comandă (Order).

Abordare greșită (anti-pattern)

public enum OrderStatus
{
    New,
    Paid,
    Shipped,
    Cancelled
}

public class Order
{
    public OrderStatus Status { get; set; }

    public void Process()
    {
        if (Status == OrderStatus.New)
        {
            Console.WriteLine("Procesare comandă nouă");
        }
        else if (Status == OrderStatus.Paid)
        {
            Console.WriteLine("Pregătire livrare");
        }
        else if (Status == OrderStatus.Shipped)
        {
            Console.WriteLine("Comanda a fost deja livrată");
        }
        else if (Status == OrderStatus.Cancelled)
        {
            throw new InvalidOperationException("Comanda este anulată");
        }
    }
}

❌ Probleme:

  • logică împrăștiată

  • metode care cresc necontrolat

  • modificări frecvente ale clasei Order


Soluția: State Pattern

Structura pattern-ului

  • State – interfață comună pentru toate stările

  • ConcreteState – implementări concrete pentru fiecare stare

  • Context – obiectul care își schimbă comportamentul


Implementare în C#

1. Interfața IOrderState

public interface IOrderState
{
    void Process(OrderContext context);
}

2. Stările concrete

Starea NewOrderState

public class NewOrderState : IOrderState
{
    public void Process(OrderContext context)
    {
        Console.WriteLine("Procesare comandă nouă");
        context.SetState(new PaidOrderState());
    }
}

Starea PaidOrderState

public class PaidOrderState : IOrderState
{
    public void Process(OrderContext context)
    {
        Console.WriteLine("Pregătire livrare");
        context.SetState(new ShippedOrderState());
    }
}

Starea ShippedOrderState

public class ShippedOrderState : IOrderState
{
    public void Process(OrderContext context)
    {
        Console.WriteLine("Comanda a fost deja livrată");
    }
}

Starea CancelledOrderState

public class CancelledOrderState : IOrderState
{
    public void Process(OrderContext context)
    {
        throw new InvalidOperationException("Comanda este anulată");
    }
}

3. Contextul OrderContext

public class OrderContext
{
    private IOrderState _state;

    public OrderContext(IOrderState initialState)
    {
        _state = initialState;
    }

    public void SetState(IOrderState state)
    {
        _state = state;
    }

    public void Process()
    {
        _state.Process(this);
    }
}

4. Utilizare

var order = new OrderContext(new NewOrderState());

order.Process(); // New -> Paid
order.Process(); // Paid -> Shipped
order.Process(); // Shipped

Avantaje

✅ elimină if / switch

✅ respectă Open/Closed Principle

✅ fiecare stare este izolată și ușor de testat

✅ cod mai curat și extensibil


Dezavantaje

⚠️ număr mai mare de clase

⚠️ poate fi overkill pentru scenarii simple


Când să folosești State Pattern?

✔️ comportamentul se schimbă semnificativ în funcție de stare

✔️ ai multe tranziții între stări

✔️ vrei să eviți logică condițională complexă

❌ NU este recomandat când ai doar 1–2 stări simple


Diferența față de Strategy Pattern

State Strategy
Starea se schimbă din interior Strategia se schimbă din exterior
Flux dependent de stare Algoritmi interschimbabili

Concluzie

State Pattern este ideal pentru modelarea proceselor reale (workflow-uri, comenzi, documente, plăți), unde comportamentul evoluează în timp.

Aplicat corect, duce la:

  • cod mai lizibil

  • mai puține bug-uri

  • extensibilitate reală

Scrie un comentariu

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