Menu
Coddy logo textTech

Strategy Kalıbı

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

Strateji deseni, bir algoritma ailesi tanımlamanıza, her birini kendi sınıfında kapsüllemenize ve bunları çalışma zamanında birbirinin yerine kullanılabilir hale getirmenize olanak tanır. Davranışı bir sınıfa doğrudan kodlamak yerine, davranışı bir arayüz aracılığıyla enjekte edersiniz; bu da onları kullanan sınıfı değiştirmeden stratejileri değiştirmenize olanak tanır.

Farklı ödeme yöntemlerini desteklemek istediğiniz bir ödeme sistemini düşünün. Her bir yöntemi işlemek için koşullu ifadeler kullanmak yerine, bir strateji arayüzü tanımlarsınız ve somut uygulamalar oluşturursunuz:

abstract class PaymentStrategy {
  void pay(double amount);
}

class CreditCardPayment implements PaymentStrategy {
  @override
  void pay(double amount) => print('Paid \$amount with Credit Card');
}

class PayPalPayment implements PaymentStrategy {
  @override
  void pay(double amount) => print('Paid \$amount with PayPal');
}

class ShoppingCart {
  PaymentStrategy _paymentStrategy;

  ShoppingCart(this._paymentStrategy);

  void setPaymentStrategy(PaymentStrategy strategy) {
    _paymentStrategy = strategy;
  }

  void checkout(double total) {
    _paymentStrategy.pay(total);
  }
}

void main() {
  var cart = ShoppingCart(CreditCardPayment());
  cart.checkout(99.99);  // Kredi Kartı ile $99.99 ödendi

  cart.setPaymentStrategy(PayPalPayment());
  cart.checkout(49.99);  // PayPal ile $49.99 ödendi
}

ShoppingCart, ödemenin nasıl çalıştığını bilmez veya umursamaz; sadece o an ayarlanmış olan stratejiye devreder. Sepet koduna dokunmadan yeni strateji sınıfları oluşturarak yeni ödeme yöntemleri ekleyebilirsiniz. Bu desen, bir eylemi gerçekleştirmenin birden fazla yolu olduğunda ve bunlar arasında dinamik olarak seçim yapmak veya geçiş yapmak istediğinizde idealdir.

challenge icon

Görev

Kolay

Strateji (Strategy) desenini kullanarak bir metin formatlama sistemi oluşturalım! Farklı formatlama stratejilerinin metne uygulanabildiği ve kullanıcıların çekirdek metin işlemcisini değiştirmeden formatlar arasında dinamik olarak geçiş yapabildiği bir sistem oluşturacaksınız.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • formatting_strategies.dart: Strateji sisteminizi burada oluşturun. String format(String text) metoduna sahip soyut bir FormattingStrategy sınıfı tanımlayın. Ardından üç somut strateji uygulayın:
    • UppercaseStrategy - metni tamamen büyük harfe dönüştürür
    • LowercaseStrategy - metni tamamen küçük harfe dönüştürür
    • TitleCaseStrategy - her kelimenin ilk harfini büyük yapar (boşluklara göre ayırın, her kelimenin ilk karakterini büyük, geri kalanını küçük harf yapın)
    Ayrıca bir FormattingStrategy tutan bir TextProcessor sınıfı oluşturun. Bu sınıf, başlangıç stratejisini kabul eden bir kurucuya (constructor), çalışma zamanında stratejiyi değiştirmek için bir setStrategy() metoduna ve mevcut stratejiyi uygulayıp formatlanmış sonucu döndüren bir process(String text) metoduna sahip olmalıdır.
  • main.dart: Formatlama stratejilerinizi içe aktarın ve Strateji deseninin dinamik davranış değişikliğine nasıl izin verdiğini gösterin. UppercaseStrategy ile başlayan bir TextProcessor oluşturun. hello world metnini işleyin ve sonucu yazdırın. Ardından LowercaseStrategy stratejisine geçin, HELLO WORLD metnini işleyin ve yazdırın. Son olarak, TitleCaseStrategy stratejisine geçin, the quick brown fox metnini işleyin ve sonucu yazdırın.

Bu, Strateji deseninin gücünü gösterir - TextProcessor sınıfınızın formatlamanın nasıl çalıştığının detaylarını bilmesine gerek yoktur. Sadece o an ayarlanmış olan stratejiye görevi devreder, bu da işlemciyi değiştirmeden yeni formatlama seçenekleri eklemeyi kolaylaştırır!

Beklenen çıktı:

HELLO WORLD
hello world
The Quick Brown Fox

Kopya kağıdı

Strateji deseni (Strategy pattern), bir algoritma ailesi tanımlar, her birini kendi sınıfına kapsüller ve çalışma zamanında birbirlerinin yerine kullanılabilir hale getirir. Davranışı kodun içine gömmek yerine, bir arayüz aracılığıyla enjekte edersiniz.

Bir strateji arayüzü tanımlayın:

abstract class PaymentStrategy {
  void pay(double amount);
}

Somut strateji uygulamaları oluşturun:

class CreditCardPayment implements PaymentStrategy {
  @override
  void pay(double amount) => print('Paid \$amount with Credit Card');
}

class PayPalPayment implements PaymentStrategy {
  @override
  void pay(double amount) => print('Paid \$amount with PayPal');
}

Stratejiyi kullanan bir bağlam (context) sınıfı oluşturun:

class ShoppingCart {
  PaymentStrategy _paymentStrategy;

  ShoppingCart(this._paymentStrategy);

  void setPaymentStrategy(PaymentStrategy strategy) {
    _paymentStrategy = strategy;
  }

  void checkout(double total) {
    _paymentStrategy.pay(total);
  }
}

Stratejileri enjekte ederek ve değiştirerek deseni kullanın:

var cart = ShoppingCart(CreditCardPayment());
cart.checkout(99.99);  // Credit Card ile $99.99 ödendi

cart.setPaymentStrategy(PayPalPayment());
cart.checkout(49.99);  // PayPal ile $49.99 ödendi

Bağlam sınıfı, uygulama detaylarını bilmeden davranışı stratejiye devreder. Mevcut kodu değiştirmeden yeni sınıflar oluşturarak yeni stratejiler ekleyebilirsiniz.

Kendin dene

import 'formatting_strategies.dart';

void main() {
  // TODO: UppercaseStrategy ile başlayan bir TextProcessor oluşturun
  
  // TODO: 'hello world' metnini işleyin ve sonucu yazdırın
  
  // TODO: LowercaseStrategy'ye geçiş yapın
  
  // TODO: 'HELLO WORLD' metnini işleyin ve sonucu yazdırın
  
  // TODO: TitleCaseStrategy'ye geçiş yapın
  
  // TODO: 'the quick brown fox' metnini işleyin ve sonucu 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