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 ödendiStrateji 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.
Görev
KolayStrateji 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ğıTextFormatterarayüzünü tanımlayın. Bir dize alan ve biçimlendirilmiş sürümü döndüren tek birString format(String text)metodu bildirmelidir.Formatters.java:TextFormatterarayü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.TextEditorsınıfınız şunlara sahip olmalıdır:Mevcut
TextFormatterstratejisini 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 birpublishText(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
TextEditoroluşturun ve herhangi bir biçimlendirici ayarlamadan önce girdi metninizlepublishTextmetodunu ç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
publishTextmetodunu 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 WorldTextEditor 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 ödendiFaydalar
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
}
}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ı