Durum Kalıbı
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 74 / 87.
State Pattern, bir nesnenin iç durumu değiştiğinde davranışını değiştirmesine olanak tanıyan davranışsal bir tasarım desenidir. Nesne sınıfını değiştiriyormuş gibi görünür, ancak gerçekte davranışı farklı durum nesnelerine devreder. Bir otomatı düşünün: Bir düğmeye basıldığında verdiği yanıt, boşta olup olmamasına, para yatırılıp yatırılmadığına veya ürün verip vermediğine bağlıdır.
Farklı durumları işlemek için karmaşık koşullu ifadeler kullanmak yerine, her durumu kendi sınıfında kapsüllersin. Bu kalıp, geçerli duruma bir başvuru tutan bir Context ve her durum için davranışı tanımlayan State sınıflarını içerir:
interface State {
void handle(Context context);
}
class Context {
private State state;
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle(this);
}
}Her somut durum, davranışı uygular ve diğer durumlara geçişleri tetikleyebilir:
class IdleState implements State {
public void handle(Context context) {
System.out.println("Idle: Insert coin to start");
context.setState(new ActiveState());
}
}
class ActiveState implements State {
public void handle(Context context) {
System.out.println("Active: Processing...");
context.setState(new IdleState());
}
}Bağlam, istekleri mevcut durumuna devreder ve durum değiştikçe davranış otomatik olarak değişir:
Context context = new Context();
context.setState(new IdleState());
context.request(); // Idle: Başlamak için jeton atın
context.request(); // Active: İşleniyor...State Pattern, bir nesnenin davranışının büyük ölçüde durumuna bağlı olduğu ve çalışma zamanında değişmesi gerektiği durumlar için idealdir. Büyük koşullu blokları ortadan kaldırır ve yeni durumlar eklemeyi kolaylaştırır; State arayüzünü uygulayan yeni bir sınıf oluşturmanız yeterlidir.
Görev
KolayState Pattern'ı kullanarak bir belge iş akışı sistemi oluşturalım! Bir belgenin Draft, Review ve Published olmak üzere farklı aşamalardan nasıl geçtiğini modelleyen bir sistem oluşturacaksınız; her durum, hangi eylemlerin kullanılabilir olduğunu ve belgeyi düzenlemeye veya onaylamaya çalıştığınızda belgenin nasıl davranacağını belirleyecek.
Kodunuzu dört dosyaya ayıracaksınız:
DocumentState.java: Tüm durumların uygulayacağıDocumentStatearayüzünü tanımlayın. İki yöntem bildirmelidir: belgeyi düzenlemeyi denemek içinedit(Document doc)ve belgeyi bir sonraki aşamaya onaylamayı/ilerletmeyi denemek içinapprove(Document doc).States.java:DocumentStatearayüzünü uygulayan üç somut durum sınıfı oluşturun:DraftState-editçağrıldığındaEditing draft...yazdırın.approveçağrıldığındaDraft approved. Moving to review.yazdırın ve belgeyiReviewStatedurumuna geçirin.ReviewState-editçağrıldığındaCannot edit during review.yazdırın (durum değişikliği olmaz).approveçağrıldığındaReview complete. Publishing document.yazdırın vePublishedStatedurumuna geçin.PublishedState-editçağrıldığındaCannot edit published document.yazdırın.approveçağrıldığındaDocument already published.yazdırın. Her iki eylem de durumu değiştirmez.Document.java: Mevcut durumu yöneten bağlam sınıfını oluşturun.Documentsınıfınız şunlara sahip olmalıdır:Mevcut
DocumentStatedeğerini tutan ve oluşturucudaDraftStateolarak başlatılan private bir alan.Mevcut durumu değiştiren bir
setState(DocumentState state)yöntemi.Mevcut durumun
edit()yöntemine yetki veren biredityöntemi.Mevcut durumun
approve()yöntemine yetki veren birapproveyöntemi.Mevcut durumun basit sınıf adını döndüren bir
getStatus()yöntemi (getClass().getSimpleName()kullanın).Main.java: Durum sisteminizi gösterin! Tek bir girdi alacaksınız: her eylemineditveyaapproveolduğu, virgülle ayrılmış bir eylem dizisi (örneğin:edit,approve,edit,approve).Bir
Documentoluşturun ve başlangıç durumunuStatus: [state]biçiminde yazdırın. Ardından her eylemi sırayla işleyerek belge üzerinde uygun yöntemi çağırın. Her eylemden sonra mevcut durumu yazdırın.
Tek bir girdi alacaksınız: virgülle ayrılmış bir eylem dizisi.
Örneğin, edit,approve,approve girdisiyle çıktınız şöyle olur:
Status: DraftState
Editing draft...
Status: DraftState
Draft approved. Moving to review.
Status: ReviewState
Review complete. Publishing document.
Status: PublishedStateAynı approve() çağrısının belgenin mevcut durumuna bağlı olarak nasıl farklı sonuçlar ürettiğine dikkat edin. State Pattern'ın özü budur! Belge, durumunu kontrol etmek için koşullu ifadeler kullanmaz; bunun yerine davranışı, eylemi uygun şekilde işleyen ve gerektiğinde geçişleri tetikleyen mevcut durum nesnesine devreder.
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
// TODO: Yeni bir Document oluştur
// TODO: İlk durumu "Status: [state]" formatında yazdır
// TODO: Bireysel eylemleri almak için girişi virgülle ayır
// TODO: Her eylem üzerinde döngü yap
// - Eylem "edit" ise, document üzerinde edit() çağır
// - Eylem "approve" ise, document üzerinde approve() çağır
// - Her eylemden sonra mevcut durumu yazdı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 DosyalarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarı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ıYineleyici KalıbıKendi başına pratik yap: Online Java derleyicisi