Behavioral — Davranışsal Desenler

State

Durum Deseni

Amaç: Bir nesnenin iç durumu değiştiğinde davranışının da değişmesini sağlamak; nesne sanki sınıfını değiştirmiş gibi görünür.

1

Basit Anlatım

Teknik terim yok — günlük hayattan bir benzetme

Bir trafik ışığını düşünün. Aynı ışık; kırmızıdayken "dur", yeşildeyken "geç", sarıdayken "hazırlan" der. Işığın kendisi değişmedi, ama içinde bulunduğu duruma göre tamamen farklı davranıyor. Her durum bir sonrakinin ne olacağını da bilir: kırmızıdan sonra yeşil, yeşilden sonra sarı gelir.

Telefonunuz

Telefonunuzun güç tuşuna bastığınızda ne olur? Telefon kilitliyse ekran açılır. Açıksa ekran kapanır. Şarjı bittiyse hiçbir şey olmaz, sadece boş pil simgesi görünür. Aynı tuş, duruma göre farklı sonuç.

Bir sipariş

İnternetten verdiğiniz sipariş "Hazırlanıyor" aşamasındayken iptal edebilirsiniz. "Kargoda" iken iptal edemezsiniz ama iade talebi açabilirsiniz. "Teslim edildi" olunca sadece iade mümkündür.

State şunu der: "Ne yapacağın, şu an hangi durumda olduğuna bağlıdır; her durum kendi kurallarını bilsin."
2

Teknik Anlamı

Bir yazılımcının bakış açısıyla

State, duruma bağlı davranışları ayrı durum sınıflarına taşır. Ana nesne (Context) mevcut durumu bir alanda tutar ve işleri ona delege eder. Durum geçişleri ya context tarafından ya da durum sınıflarının kendisi tarafından yapılır.

Çözdüğü problem

Durum yönetimi olmadan kod şöyle görünür: her metotta switch (status) { case Pending: ... case Shipped: ... }. Yeni bir durum eklendiğinde tüm switch'lerin bulunup güncellenmesi gerekir ve bir tanesi unutulursa hata oluşur.

Katılımcılar

Strategy'den farkı

Yapıları neredeyse aynıdır. Strategy'de algoritmayı genellikle istemci seçer ve stratejiler birbirini tanımaz. State'te ise durumlar kendi aralarında geçiş yapar ve birbirlerini bilirler.

Avantajlar

Dezavantajlar

3

C# ile Uygulama

Adım adım, çalışan kod örneği

Senaryo: Bir e-ticaret siparişinin yaşam döngüsü: Hazırlanıyor → Kargoda → Teslim Edildi, ayrıca İptal Edildi.

Adım 1 State arayüzü

public interface IOrderState
{
    string Name { get; }
    void Next(Order order);
    void Cancel(Order order);
}

Adım 2 Context: sipariş

Order sınıfında hiç switch yok; tüm işi mevcut duruma delege ediyor.

public class Order
{
    public string Id { get; }
    public IOrderState State { get; private set; } = new PreparingState();

    public Order(string id) => Id = id;

    public void TransitionTo(IOrderState state)
    {
        Console.WriteLine($"  {Id}: {State.Name} -> {state.Name}");
        State = state;
    }

    public void Next() => State.Next(this);
    public void Cancel() => State.Cancel(this);
}

Adım 3 Somut durumlar

Her durum, hangi işlemlere izin verdiğini ve bir sonraki durumun ne olacağını kendisi bilir.

public class PreparingState : IOrderState
{
    public string Name => "Hazırlanıyor";
    public void Next(Order o) => o.TransitionTo(new ShippedState());
    public void Cancel(Order o) => o.TransitionTo(new CancelledState());
}

public class ShippedState : IOrderState
{
    public string Name => "Kargoda";
    public void Next(Order o) => o.TransitionTo(new DeliveredState());
    public void Cancel(Order o) =>
        Console.WriteLine("  ! Kargodaki sipariş iptal edilemez, teslimden sonra iade açın.");
}

public class DeliveredState : IOrderState
{
    public string Name => "Teslim Edildi";
    public void Next(Order o) => Console.WriteLine("  ! Sipariş zaten teslim edildi.");
    public void Cancel(Order o) => Console.WriteLine("  ! Teslim edilen sipariş için iade açın.");
}

public class CancelledState : IOrderState
{
    public string Name => "İptal Edildi";
    public void Next(Order o) => Console.WriteLine("  ! İptal edilmiş sipariş ilerletilemez.");
    public void Cancel(Order o) => Console.WriteLine("  ! Sipariş zaten iptal edilmiş.");
}

Adım 4 Kullanım

Tüm parçaları bir araya getiren istemci (client) kodu:

Console.WriteLine("Sipariş A:");
var a = new Order("A-100");
a.Next();       // Hazırlanıyor -> Kargoda
a.Cancel();     // izin yok
a.Next();       // Kargoda -> Teslim Edildi
a.Next();       // izin yok

Console.WriteLine("Sipariş B:");
var b = new Order("B-200");
b.Cancel();     // Hazırlanıyor -> İptal Edildi
b.Next();       // izin yok
Console.WriteLine($"Son durumlar: A = {a.State.Name}, B = {b.State.Name}");

Konsol çıktısı

Sipariş A:
  A-100: Hazırlanıyor -> Kargoda
  ! Kargodaki sipariş iptal edilemez, teslimden sonra iade açın.
  A-100: Kargoda -> Teslim Edildi
  ! Sipariş zaten teslim edildi.
Sipariş B:
  B-200: Hazırlanıyor -> İptal Edildi
  ! İptal edilmiş sipariş ilerletilemez.
Son durumlar: A = Teslim Edildi, B = İptal Edildi

Kodda dikkat edilmesi gerekenler

Özetle: State, duruma bağlı davranışları ayrı sınıflara taşır; nesne, durumu değiştikçe davranışını da değiştirir ve büyük switch blokları ortadan kalkar.
← Ana sayfaya dön