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ü, bu davranışı uygulayan somut durum sınıfları ve geçerli duruma bir başvuru tutan bir bağlam sınıfı:
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 mevcut durumu tutar ve eylemleri ona devreder. Durum nesneleri, bağlam üzerinde SetState() çağrısı yaparak 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ı belirli durumlar (kırmızı, sarı, yeşil) arasında geçiş 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ülleyeceksin.
kodunu üç dosya arasında düzenleyeceksin:
TrafficLightState.cs:ITrafficLightStatead alanında birTrafficarayüzü veChange(TrafficLight light)metodunu tanımla. Ardından üç somut durum sınıfı oluştur:RedState-ChangeçağrıldığındaRed - 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ştur. Bu, mevcut durumu yöneten bağlam sınıfındır. Varsayılan olarakRedStatedurumunda başlamalı ve şunlara sahip olmalıdır:- Durum nesnelerinin geçişleri tetiklemek için kullandığı bir
SetState(ITrafficLightState state)metodu - Mevcut durumun
Change()metoduna delege eden birChangemetodu
- Durum nesnelerinin geçişleri tetiklemek için kullandığı bir
Program.cs: BirTrafficLightoluşturarak ve girdiye bağlı olarak durum değişiklikleri arasında geçiş yaparak her şeyi bir araya getir.
Bir girdi alacaksın:
- Trafik ışığının kaç kez değiştirileceği (bir tamsayı)
Bir TrafficLight oluştur (kırmızıda başlar) ve belirtilen sayıda Change() çağrısı yap.
Örneğin girdi 3 ise çıktı şu şekilde olmalıdır:
Red - Stop! Changing to Green...
Green - Go! Changing to Yellow...
Yellow - Caution! Changing to Red...Girdi 5 ise ışık yeniden başlangıç durumuna 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 rengin ne anlama geldiği veya sırada neyin geleceğiyle ilgili hiçbir mantık içermediğine dikkat et - tüm bu bilgi ayrı durum sınıflarında bulunur. Her durum kendi davranışından ve bir sonraki duruma geçişi tetiklemekten sorumludur!
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ıKendi başına pratik yap: Online C# derleyicisi