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.
Görev
KolayState 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:Trafficad alanında (namespace),Change(TrafficLight light)metoduna sahip birITrafficLightStatearayü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 ışığıGreenStatedurumuna geçirirGreenState-Green - Go! Changing to Yellow...yazdırır veYellowStatedurumuna geçirirYellowState-Yellow - Caution! Changing to Red...yazdırır veRedStatedurumuna geçirir
TrafficLight.cs: Aynı ad alanında birTrafficLightsınıfı oluşturun. Bu, mevcut durumu koruyan bağlam (context) sınıfınızdır. Varsayılan olarakRedStateile 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
Changemetoduna yetki devreden birChange()metodu
- Durum nesnelerinin geçişleri tetiklemek için kullandığı bir
Program.cs: BirTrafficLightoluş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
}
}
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
1OOP Temelleri
Harici Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci Kayıtları