Menu
Coddy logo textTech

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.

challenge icon

Görev

Kolay

State 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ğı DocumentState arayüzünü tanımlayın. İki yöntem bildirmelidir: belgeyi düzenlemeyi denemek için edit(Document doc) ve belgeyi bir sonraki aşamaya onaylamayı/ilerletmeyi denemek için approve(Document doc).
  • States.java: DocumentState arayüzünü uygulayan üç somut durum sınıfı oluşturun:

    DraftState - edit çağrıldığında Editing draft... yazdırın. approve çağrıldığında Draft approved. Moving to review. yazdırın ve belgeyi ReviewState durumuna geçirin.

    ReviewState - edit çağrıldığında Cannot edit during review. yazdırın (durum değişikliği olmaz). approve çağrıldığında Review complete. Publishing document. yazdırın ve PublishedState durumuna geçin.

    PublishedState - edit çağrıldığında Cannot edit published document. yazdırın. approve çağrıldığında Document 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. Document sınıfınız şunlara sahip olmalıdır:

    Mevcut DocumentState değerini tutan ve oluşturucuda DraftState olarak başlatılan private bir alan.

    Mevcut durumu değiştiren bir setState(DocumentState state) yöntemi.

    Mevcut durumun edit() yöntemine yetki veren bir edit yöntemi.

    Mevcut durumun approve() yöntemine yetki veren bir approve yö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 eylemin edit veya approve olduğu, virgülle ayrılmış bir eylem dizisi (örneğin: edit,approve,edit,approve).

    Bir Document oluşturun ve başlangıç durumunu Status: [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: PublishedState

Aynı 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
    }
}
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

Kendi başına pratik yap: Online Java derleyicisi