Menu
Coddy logo textTech

Durum Kalıbı

Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 60 / 70.

State deseni, bir nesnenin iç durumu değiştiğinde davranışını değiştirmesine olanak tanıyan davranışsal bir desendir. Farklı durumları yönetmek için karmaşık koşullu ifadeler kullanmak yerine, her durumu kendi sınıfında kapsüller ve davranışı mevcut durum nesnesine devredersiniz.

Desen üç bileşenden oluşur: duruma özgü davranışı tanımlayan bir durum arayüzü (state interface), bu davranışı uygulayan somut durum sınıfları (concrete state classes) ve mevcut duruma bir referans tutan bir bağlam sınıfı (context class):

public interface IDocumentState
{
    void Publish(Document doc);
}

public class DraftState : IDocumentState
{
    public void Publish(Document doc)
    {
        Console.WriteLine("Moving to moderation");
        doc.SetState(new ModerationState());
    }
}

public class ModerationState : IDocumentState
{
    public void Publish(Document doc)
    {
        Console.WriteLine("Publishing document");
        doc.SetState(new PublishedState());
    }
}

public class PublishedState : IDocumentState
{
    public void Publish(Document doc)
    {
        Console.WriteLine("Already published");
    }
}

Bağlam (context), mevcut durumu tutar ve eylemleri ona devreder. Durum nesneleri, bağlam üzerinde SetState() metodunu çağırarak geçişleri tetikleyebilir:

public class Document
{
    private IDocumentState _state = new DraftState();
    
    public void SetState(IDocumentState state) => _state = state;
    
    public void Publish() => _state.Publish(this);
}

var doc = new Document();
doc.Publish();  // Moderasyona taşınıyor
doc.Publish();  // Doküman yayınlanıyor
doc.Publish();  // Zaten yayınlandı

State deseni, mevcut durumu kontrol eden karmaşık if-else veya switch ifadelerini ortadan kaldırır. Her bir durum sınıfı yalnızca kendi davranışını yönetir; bu da kodun bakımını yapmayı ve yeni durumlarla genişletmeyi kolaylaştırır.

challenge icon

Görev

Kolay

State desenini kullanarak bir trafik ışığı sistemi oluşturalım. Trafik ışıkları farklı durumlar (kırmızı, sarı, yeşil) arasında döngü yapar ve her durum, ışık değiştiğinde ne olacağını belirler. Karmaşık koşullu ifadeler kullanmak yerine, her ışık durumunu kendi sınıfında kapsülleyeceksiniz.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • TrafficLightState.cs: Traffic ad alanında (namespace), Change(TrafficLight light) metoduna sahip bir ITrafficLightState arayüzü tanımlayın. Ardından üç somut durum sınıfı oluşturun:
    • RedState - Change çağrıldığında, Red - Stop! Changing to Green... yazdırır ve ışığı GreenState durumuna geçirir
    • GreenState - Green - Go! Changing to Yellow... yazdırır ve YellowState durumuna geçirir
    • YellowState - Yellow - Caution! Changing to Red... yazdırır ve RedState durumuna geçirir
  • TrafficLight.cs: Aynı ad alanında bir TrafficLight sınıfı oluşturun. Bu, mevcut durumu koruyan bağlam (context) sınıfınızdır. Varsayılan olarak RedState ile başlamalıdır ve şunlara sahip olmalıdır:
    • Durum nesnelerinin geçişleri tetiklemek için kullandığı bir SetState(ITrafficLightState state) metodu
    • Mevcut durumun Change metoduna yetki devreden bir Change() metodu
  • Program.cs: Bir TrafficLight oluşturarak ve girişe göre durum değişiklikleri arasında döngü kurarak her şeyi bir araya getirin.

Bir girdi alacaksınız:

  • Trafik ışığının kaç kez değiştirileceği (bir tam sayı)

Bir TrafficLight (kırmızıdan başlayan) oluşturun ve belirtilen sayıda Change() metodunu çağırın.

Örneğin, girdi 3 ise, çıktı şöyle olmalıdır:

Red - Stop! Changing to Green...
Green - Go! Changing to Yellow...
Yellow - Caution! Changing to Red...

Girdi 5 ise, ışık döngüsü başa döner:

Red - Stop! Changing to Green...
Green - Go! Changing to Yellow...
Yellow - Caution! Changing to Red...
Red - Stop! Changing to Green...
Green - Go! Changing to Yellow...

TrafficLight sınıfının her bir rengin ne anlama geldiği veya bir sonraki rengin ne olduğu hakkında hiçbir mantık içermediğine dikkat edin; tüm bu bilgi bireysel durum sınıflarında yaşar. Her durum kendi davranışından ve bir sonraki duruma geçişi tetiklemekten sorumludur!

Kopya kağıdı

State deseni, bir nesnenin iç durumu değiştiğinde davranışını değiştirmesine olanak tanıyan davranışsal bir desendir. Karmaşık koşullu ifadeler kullanmak yerine, her durumu kendi sınıfında kapsüller ve davranışı mevcut durum nesnesine devredersiniz.

Desen üç bileşenden oluşur:

  • State arayüzü: Duruma özgü davranışı tanımlar
  • Somut durum sınıfları: Her durum için davranışı uygular
  • Context sınıfı: Mevcut duruma bir referans tutar

Örnek uygulama:

// State arayüzü
public interface IDocumentState
{
    void Publish(Document doc);
}

// Somut durum sınıfları
public class DraftState : IDocumentState
{
    public void Publish(Document doc)
    {
        Console.WriteLine("Moving to moderation");
        doc.SetState(new ModerationState());
    }
}

public class ModerationState : IDocumentState
{
    public void Publish(Document doc)
    {
        Console.WriteLine("Publishing document");
        doc.SetState(new PublishedState());
    }
}

public class PublishedState : IDocumentState
{
    public void Publish(Document doc)
    {
        Console.WriteLine("Already published");
    }
}

// Context sınıfı
public class Document
{
    private IDocumentState _state = new DraftState();
    
    public void SetState(IDocumentState state) => _state = state;
    
    public void Publish() => _state.Publish(this);
}

// Kullanım
var doc = new Document();
doc.Publish();  // Moderasyona taşınıyor
doc.Publish();  // Doküman yayınlanıyor
doc.Publish();  // Zaten yayınlandı

Context, mevcut durumu tutar ve eylemleri ona devreder. Durum nesneleri, context üzerinde SetState() çağırarak geçişleri tetikleyebilir. Bu, karmaşık if-else veya switch ifadelerini ortadan kaldırarak kodun bakımını ve yeni durumlarla genişletilmesini kolaylaştırır.

Kendin dene

using System;
using Traffic;

class Program
{
    public static void Main(String[] args)
    {
        // Trafik ışığının kaç kez değiştirileceğini oku
        int n = Convert.ToInt32(Console.ReadLine());

        // TODO: Bir TrafficLight örneği oluştur (varsayılan olarak RedState ile başlar)

        // TODO: Bir döngü kullanarak Change() metodunu n kez çağır
    }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler