Strategy Pattern (Strateji Tasarım Kalıbı), belirli bir işlemi gerçekleştiren farklı algoritmaların runtime (çalışma zamanı) sırasında seçilebilmesini sağlayan davranışsal (behavioral) tasarım desenlerinden biridir. Bu desen, if-else veya switch-case gibi yapılar kullanmadan farklı stratejileri değiştirmeyi kolaylaştırır.
Ne Zaman Kullanılmalıdır?
Strategy Pattern şu durumlarda kullanışlıdır:
- Farklı algoritmalar arasından çalışma zamanında seçim yapılması gerektiğinde.
- Kodun okunabilirliğini artırmak ve büyük if-else bloklarından kaçınmak gerektiğinde.
- Belli bir işlemi farklı yollarla gerçekleştirme ihtiyacı olduğunda.
- Sınıflar arası bağımlılığı azaltmak ve kodu daha esnek hale getirmek gerektiğinde.
Avantajları :
- Gevşek bağlılık (Loose Coupling): Ana sınıf, belirli algoritmalara bağımlı değildir.
- Genişletilebilirlik (Extensibility): Yeni algoritmalar eklenerek sistem genişletilebilir.
- Kodun okunabilirliğini artırır: Büyük if-else bloklarını ortadan kaldırır.
- Test edilebilirliği artırır: Farklı stratejiler ayrı sınıflar halinde tanımlandığı için birim testleri daha kolay yapılabilir.
Dezavantajları :
- Kod karmaşıklığını artırabilir: Stratejiler için ayrı sınıflar oluşturmak, küçük projelerde gereksiz karmaşıklık yaratabilir.
- İlgili nesnelerin dinamik olarak seçilmesi için ek yönetim gerektirir.
Strategy Pattern Kullanım Biçimleri
1. Strategy Arayüzü ve Concrete Strategy Sınıfları
// Strateji Arayüzü
interface PaymentStrategy {
void pay(int amount);
}
// Concrete Strategy: Kredi Kartı ile ödeme
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(int amount) {
System.out.println(amount + " TL kredi kartı ile ödendi. Kart No: " + cardNumber);
}
}
// Concrete Strategy: PayPal ile ödeme
class PayPalPayment implements PaymentStrategy {
private String email;
public PayPalPayment(String email) {
this.email = email;
}
@Override
public void pay(int amount) {
System.out.println(amount + " TL PayPal ile ödendi. E-posta: " + email);
}
}
2. Context Sınıfı (Stratejiyi Seçen Sınıf)
class PaymentContext {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void executePayment(int amount) {
paymentStrategy.pay(amount);
}
}
3. Kullanım
public class Main {
public static void main(String[] args) {
PaymentContext context = new PaymentContext();
context.setPaymentStrategy(new CreditCardPayment("1234-5678-9012-3456"));
context.executePayment(100);
context.setPaymentStrategy(new PayPalPayment("example@email.com"));
context.executePayment(200);
}
}
Çıktı:
100 TL kredi kartı ile ödendi. Kart No: 1234-5678-9012-3456
200 TL PayPal ile ödendi. E-posta: example@email.com
Gerçek Dünya Senaryosu: Ulaşım Stratejisi Seçimi
// Strateji Arayüzü
interface TransportationStrategy {
void travel(String destination);
}
// Concrete Strategy: Araba ile yolculuk
class CarTravel implements TransportationStrategy {
@Override
public void travel(String destination) {
System.out.println(destination + " konumuna araba ile gidiliyor.");
}
}
// Concrete Strategy: Tren ile yolculuk
class TrainTravel implements TransportationStrategy {
@Override
public void travel(String destination) {
System.out.println(destination + " konumuna tren ile gidiliyor.");
}
}
// Concrete Strategy: Uçak ile yolculuk
class AirplaneTravel implements TransportationStrategy {
@Override
public void travel(String destination) {
System.out.println(destination + " konumuna uçak ile gidiliyor.");
}
}
// Context Sınıfı
class TravelContext {
private TransportationStrategy strategy;
public void setStrategy(TransportationStrategy strategy) {
this.strategy = strategy;
}
public void executeTravel(String destination) {
strategy.travel(destination);
}
}
Kullanım
public class Main {
public static void main(String[] args) {
TravelContext travelContext = new TravelContext();
travelContext.setStrategy(new CarTravel());
travelContext.executeTravel("İstanbul");
travelContext.setStrategy(new TrainTravel());
travelContext.executeTravel("Ankara");
travelContext.setStrategy(new AirplaneTravel());
travelContext.executeTravel("New York");
}
}
Çıktı:
İstanbul konumuna araba ile gidiliyor.
Ankara konumuna tren ile gidiliyor.
New York konumuna uçak ile gidiliyor.
Sonuç
Strategy Design Pattern, bir işlemin farklı yollarla gerçekleştirilebilmesini sağladığı için esneklik ve genişletilebilirlik açısından çok güçlüdür. Gerçek dünyada şu senaryolarda yaygın olarak kullanılır:
- Ödeme yöntemleri (Kredi kartı, PayPal, Bitcoin vs.)
- Grafik işleme stratejileri (2D vs. 3D çizim yöntemleri)
- Oyun geliştirme (Farklı yapay zeka hareket stratejileri)
- Veri sıkıştırma algoritmaları (ZIP, RAR, GZIP vs.)
Strategy Pattern sayesinde, sistemin farklı davranışlarını kod tekrarına ve büyük if-else bloklarına ihtiyaç duymadan yönetebilirsin. 🚀