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 (Durum Deseni), 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 makinesini düşünün: Bir düğmeye basılmasına verdiği yanıt; makinenin boşta olmasına, para atılmış olmasına veya bir ürün veriyor olmasına bağlı olarak değişir.

Farklı durumları yönetmek için karmaşık koşullu ifadeler kullanmak yerine, her durumu kendi sınıfı içinde kapsüllersiniz. Bu desen, mevcut duruma bir referans 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 bir 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());
    }
}

Context, 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();  // Boşta: Başlamak için madeni para yerleştirin
context.request();  // Aktif: İşleniyor...

State Deseni, bir nesnenin davranışı büyük ölçüde durumuna bağlı olduğunda ve çalışma zamanında değişmesi gerektiğinde idealdir. Büyük koşullu blokları ortadan kaldırır ve yeni durumlar eklemeyi kolaylaştırır; sadece 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 farklı aşamalardan (Draft, Review ve Published) nasıl geçtiğini modelleyen bir sistem oluşturacaksınız; her durum, hangi eylemlerin mevcut olduğunu ve belgeyi düzenlemeye veya onaylamaya çalıştığınızda belgenin nasıl davranacağını belirleyecektir.

Kodunuzu dört dosya halinde düzenleyeceksiniz:

  • DocumentState.java: Tüm durumların uygulayacağı DocumentState arayüzünü tanımlayın. İki yöntem bildirmelidir: belgeyi düzenlemeye çalışmak için edit(Document doc) ve belgeyi onaylamak/bir sonraki aşamaya geçirmek 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 yok). approve çağrıldığında, Review complete. Publishing document. yazdırın ve PublishedState durumuna geçirin.

    PublishedState - edit çağrıldığında, Cannot edit published document. yazdırın. approve çağrıldığında, Document already published. yazdırın. Hiçbir eylem durumu değiştirmez.

  • Document.java: Mevcut durumu koruyan bağlam (context) sınıfını oluşturun. Document sınıfınız şunlara sahip olmalıdır:

    Mevcut DocumentState nesnesini tutan ve yapıcıda (constructor) DraftState olarak başlatılan özel bir alan.

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

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

    Mevcut durumun approve yöntemine yetki devreden 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! Bir girdi alacaksınız: her bir eylemin edit veya approve olduğu virgülle ayrılmış bir dize (örneğin: edit,approve,edit,approve).

    Bir Document oluşturun ve başlangıç durumunu Status: [state] formatında yazdırın. Ardından her eylemi sırayla işleyin ve belgedeki uygun yöntemi çağırın. Her eylemden sonra mevcut durumu yazdırın.

Bir girdi alacaksınız: virgülle ayrılmış bir eylem dizisi.

Örneğin, edit,approve,approve girdisi ile çıktınız şöyle olacaktır:

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'in ö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.

Kopya kağıdı

Durum Deseni (State Pattern), bir nesnenin iç durumu değiştiğinde davranışını değiştirmesine olanak tanıyan ve karmaşık koşullu ifadeler kullanmak yerine davranışı farklı durum nesnelerine devreden davranışsal bir tasarım desenidir.

Desen, mevcut duruma bir referans tutan bir Context ve her durum için davranışı tanımlayan State sınıflarından oluşur:

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());
    }
}

Context, 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: Insert coin to start
context.request();  // Active: Processing...

Durum Deseni, 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.

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şturun
        
        // TODO: Başlangıç durumunu "Status: [state]" formatında yazdırın
        
        // TODO: Münferit eylemleri elde etmek için girişi virgüle göre bölün
        
        // TODO: Her bir eylem üzerinde döngü kurun
        // - Eğer eylem "edit" ise, belge üzerinde edit() metodunu çağırın
        // - Eğer eylem "approve" ise, belge üzerinde approve() metodunu çağırın
        // - Her eylemden sonra mevcut durumu yazdırın
    }
}
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