Menu
Coddy logo textTech

Strategy Kalıbı

Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 69 / 87.

Strateji Deseni (Strategy Pattern), bir algoritma ailesi tanımlamanıza, her birini kendi sınıfında kapsüllemenize ve bunları birbirinin yerine kullanılabilir hale getirmenize olanak tanıyan davranışsal bir tasarım desenidir. Belirli bir davranışı doğrudan koda yazmak yerine, algoritmaları kullanan kodu değiştirmeden çalışma zamanında algoritmalar arasında geçiş yapabilirsiniz.

Birden fazla ödeme yöntemini destekleyen bir ödeme sistemi hayal edin. Strateji Deseni (Strategy Pattern) olmadan, karmaşık koşullu mantıklarla uğraşmak zorunda kalırsınız. Bu desenle, her ödeme yöntemi kendi stratejisi haline gelir:

interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via Credit Card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via PayPal");
    }
}

context (bağlam) sınıfı, bir stratejiye referans tutar ve işi ona devreder. Buradaki kilit nokta, bağlamın hangi somut stratejiyi kullandığını bilmemesidir; yalnızca arayüzü (interface) bilir:

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }
    
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

Artık ödeme davranışını dinamik olarak değiştirebilirsiniz:

ShoppingCart cart = new ShoppingCart();

cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100);  // Kredi Kartı ile 100 ödendi

cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50);   // PayPal ile 50 ödendi

Strateji Deseni (Strategy Pattern), bir eylemi gerçekleştirmenin birden fazla yolu olduğunda ve bunlar arasında kolayca geçiş yapmak istediğinizde parlar. Yeni bir ödeme yöntemi eklemek, sadece PaymentStrategy arayüzünü uygulayan yeni bir sınıf oluşturmak anlamına gelir; mevcut kodda herhangi bir değişiklik yapılması gerekmez.

challenge icon

Görev

Kolay

Strateji Desenini (Strategy Pattern) kullanarak bir metin biçimlendirme sistemi oluşturalım! Farklı biçimlendirme stratejilerinin çalışma zamanında değiştirilebildiği ve metni çeşitli şekillerde dönüştürebildiği bir sistem oluşturacaksınız; bu, birden fazla çıktı formatını desteklemesi gereken bir uygulama için mükemmeldir.

Kodunuzu dört dosya halinde düzenleyeceksiniz:

  • TextFormatter.java: Tüm biçimlendirme stratejilerinin uygulayacağı TextFormatter arayüzünü tanımlayın. Bir dize alan ve biçimlendirilmiş sürümü döndüren tek bir String format(String text) metodu bildirmelidir.
  • Formatters.java: TextFormatter arayüzünüzü uygulayan üç somut strateji oluşturun:

    UpperCaseFormatter - metni tamamen büyük harflere dönüştürür.

    LowerCaseFormatter - metni tamamen küçük harflere dönüştürür.

    TitleCaseFormatter - her kelimenin ilk harfini büyük, geri kalanını küçük harf yapar. Kelimeler boşluklarla ayrılır.

  • TextEditor.java: Bir biçimlendirme stratejisi kullanan bağlam (context) sınıfını oluşturun. TextEditor sınıfınız şunlara sahip olmalıdır:

    Mevcut TextFormatter stratejisini tutmak için özel (private) bir alan.

    Aktif biçimlendirme stratejisini değiştiren bir setFormatter(TextFormatter formatter) metodu.

    Mevcut biçimlendiriciyi metne uygulayan ve Published: [formatted text] yazdıran bir publishText(String text) metodu. Eğer herhangi bir biçimlendirici ayarlanmamışsa, Published: [original text] şeklinde metni değiştirmeden yazdırmalıdır.

  • Main.java: Strateji sisteminizi bir araya getirin! İki girdi alacaksınız: biçimlendirilecek metin (String) ve biçimlendirme stili (String: "upper", "lower" veya "title").

    Bir TextEditor oluşturun ve herhangi bir biçimlendirici ayarlamadan önce girdi metninizle publishText metodunu çağırın (varsayılan davranışı göstermek için).

    Ardından, stil girdisine bağlı olarak uygun biçimlendirici stratejisini ayarlayın ve biçimlendirilmiş sonucu göstermek için aynı metinle publishText metodunu tekrar çağırın.

Sırasıyla iki girdi alacaksınız: biçimlendirilecek metin (String) ve biçimlendirme stili (String).

Örneğin, hello world ve title girdileriyle çıktınız şöyle olacaktır:

Published: hello world
Published: Hello World

TextEditor sınıfının belirli biçimlendirme mantığı hakkında hiçbir şey bilmediğine dikkat edin; sadece o anda ayarlanmış olan stratejiye görevi devreder. Bu, editör koduna dokunmadan yeni biçimlendirme stilleri eklemeyi çok kolaylaştırır!

Kopya kağıdı

Strateji Deseni (Strategy Pattern), bir algoritma ailesi tanımlayan, her birini kendi sınıfına kapsülleyen ve bunları birbirinin yerine kullanılabilir hale getiren davranışsal bir tasarım desenidir. Algoritmaların, onları kullanan kodu değiştirmeden çalışma zamanında değiştirilmesine olanak tanır.

Key Components

Strateji Arayüzü (Strategy Interface): Tüm somut stratejiler için ortak arayüzü tanımlar.

interface PaymentStrategy {
    void pay(int amount);
}

Somut Stratejiler (Concrete Strategies): Strateji arayüzünü belirli algoritmalarla uygularlar.

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via Credit Card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via PayPal");
    }
}

Bağlam Sınıfı (Context Class): Bir stratejiye referans tutar ve işi ona devreder. Bağlam sadece arayüzü bilir, somut uygulamayı bilmez.

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }
    
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

Kullanım

Stratejiler çalışma zamanında dinamik olarak değiştirilebilir:

ShoppingCart cart = new ShoppingCart();

cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100);  // Kredi Kartı ile 100 ödendi

cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50);   // PayPal ile 50 ödendi

Faydalar

Strateji Deseni, bir eylemi gerçekleştirmenin birden fazla yolu olduğunda ve bunlar arasında kolayca geçiş yapmak istediğinizde idealdir. Yeni bir strateji eklemek, sadece strateji arayüzünü uygulayan yeni bir sınıf oluşturmak anlamına gelir; mevcut kodda herhangi bir değişiklik yapılması gerekmez.

Kendin dene

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String text = scanner.nextLine();
        String style = scanner.nextLine();
        
        // TODO: Bir TextEditor örneği oluşturun
        
        // TODO: Giriş metni ile publishText'i çağırın (herhangi bir biçimlendirici ayarlamadan önce)
        
        // TODO: Stil girişine göre ("upper", "lower" veya "title"),
        // uygun biçimlendiriciyi ayarlayın ve publishText'i tekrar çağı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