Strategy Kalıbı
Coddy'nin Python Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 48 / 64.
Strateji Deseni (Strategy Pattern), bir algoritma ailesi tanımlar, her birini kapsüller ve onları birbirinin yerine kullanılabilir hale getirir. İstemci kodunu değiştirmeden algoritmaları çalışma zamanında değiştirebilirsiniz.
İşte farklı ödeme yöntemleri için basit strateji sınıfları:
class CreditCard:
def pay(self, amount):
return f"Paid ${amount} with Credit Card"
class PayPal:
def pay(self, amount):
return f"Paid ${amount} with PayPal"
class Bitcoin:
def pay(self, amount):
return f"Paid ${amount} with Bitcoin"Her bir strateji aynı metodu (pay) uygular ancak farklı bir davranış sergiler.
Stratejileri kullanan bir bağlam (context) sınıfı oluşturun:
class ShoppingCart:
def __init__(self):
self.total = 0
self.payment_strategy = None
def add_item(self, price):
self.total += price
def set_payment_strategy(self, strategy):
self.payment_strategy = strategy
def checkout(self):
return self.payment_strategy.pay(self.total)Context sınıfı farklı ödeme stratejileri arasında geçiş yapabilir.
Strateji desenini kullanın:
cart = ShoppingCart()
cart.add_item(50)
cart.add_item(30)
# Kredi kartı stratejisini kullan
cart.set_payment_strategy(CreditCard())
print(cart.checkout())
# PayPal stratejisine geç
cart.set_payment_strategy(PayPal())
print(cart.checkout())Sıralama stratejileriyle başka bir örnek oluşturalım:
class BubbleSort:
def sort(self, data):
return f"Bubble sorted: {sorted(data)}"
class QuickSort:
def sort(self, data):
return f"Quick sorted: {sorted(data)}"
class Sorter:
def __init__(self, strategy):
self.strategy = strategy
def set_strategy(self, strategy):
self.strategy = strategy
def sort_data(self, data):
return self.strategy.sort(data)
# Farklı sıralama stratejileri kullanın
numbers = [3, 1, 4, 1, 5]
sorter = Sorter(BubbleSort())
print(sorter.sort_data(numbers))
sorter.set_strategy(QuickSort())
print(sorter.sort_data(numbers))Çıktı:
Paid $80 with Credit Card
Paid $80 with PayPal
Bubble sorted: [1, 1, 3, 4, 5]
Quick sorted: [1, 1, 3, 4, 5]Anahtar Nokta: Strateji Deseni (Strategy Pattern), algoritmaları çalışma zamanında (runtime) değiştirmenize olanak tanır. Aynı arayüze (interface) sahip farklı stratejiler tanımlayın, ardından hangi stratejinin kullanılacağını context sınıfının seçmesine izin verin. Bu, mevcut kodu değiştirmeden kodunuzu esnek hale getirir ve yeni algoritmalarla genişletilmesini kolaylaştırır.
Görev
OrtaAlışveriş sistemimiz için yeni bir BitcoinPayment stratejisi uygulayın.
Göreviniz şunları yapmaktır:
- PaymentStrategy arayüzünü uygulayan bir BitcoinPayment sınıfı oluşturun
- Yapıcı metodunda (constructor) bir wallet_address kabul etmelidir
- pay metodu tam olarak şunu yazdırmalıdır:
Paying $X using Bitcoin wallet: Y(burada X miktar, Y ise cüzdan adresidir) - pay metodu yazdırma işleminden sonra True döndürmelidir
- Şunları yapan bir main fonksiyonu yazın:
- Bir alışveriş sepeti (shopping cart) oluşturur
- Sepete 1200$ değerinde bir "Laptop" ve 100$ değerinde "Headphones" ekler
- "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa" cüzdan adresiyle bir BitcoinPayment oluşturur
- Bu ödeme stratejisini sepete tanımlar
- checkout metodunu çağırır
Başlangıç kodu alt kısımda zaten if __name__ == "__main__": bloğunu içermektedir — bunu kendiniz eklemenize gerek yoktur. Bu, main() fonksiyonunuzun yalnızca dosya doğrudan çalıştırıldığında (başka bir modül tarafından içe aktarıldığında değil) çalışmasını sağlayan bir Python kuralıdır. Sadece main() fonksiyonunuzu tanımlayın; sağlanan blok onu otomatik olarak çağıracaktır.
Ders örneklerinde gösterilen yapıyı takip edin.
Kopya kağıdı
Strateji Deseni (Strategy Pattern), bir algoritma ailesi tanımlar, her birini kapsüller ve onları birbirinin yerine kullanılabilir hale getirir. İstemci kodunu değiştirmeden çalışma zamanında algoritmalar arasında geçiş yapabilirsiniz.
Aynı arayüze sahip strateji sınıfları oluşturun:
class CreditCard:
def pay(self, amount):
return f"Paid ${amount} with Credit Card"
class PayPal:
def pay(self, amount):
return f"Paid ${amount} with PayPal"
class Bitcoin:
def pay(self, amount):
return f"Paid ${amount} with Bitcoin"Stratejileri kullanan bir bağlam (context) sınıfı oluşturun:
class ShoppingCart:
def __init__(self):
self.total = 0
self.payment_strategy = None
def add_item(self, price):
self.total += price
def set_payment_strategy(self, strategy):
self.payment_strategy = strategy
def checkout(self):
return self.payment_strategy.pay(self.total)Strateji desenini kullanın:
cart = ShoppingCart()
cart.add_item(50)
cart.add_item(30)
# Use credit card strategy
cart.set_payment_strategy(CreditCard())
print(cart.checkout())
# Switch to PayPal strategy
cart.set_payment_strategy(PayPal())
print(cart.checkout())Sıralama stratejileri ile başka bir örnek:
class BubbleSort:
def sort(self, data):
return f"Bubble sorted: {sorted(data)}"
class QuickSort:
def sort(self, data):
return f"Quick sorted: {sorted(data)}"
class Sorter:
def __init__(self, strategy):
self.strategy = strategy
def set_strategy(self, strategy):
self.strategy = strategy
def sort_data(self, data):
return self.strategy.sort(data)Kendin dene
from abc import ABC, abstractmethod
class PaymentStrategy(ABC):
@abstractmethod
def pay(self, amount):
pass
class CreditCardPayment(PaymentStrategy):
def __init__(self, card_number, expiry_date, cvv):
self.card_number = card_number
self.expiry_date = expiry_date
self.cvv = cvv
def pay(self, amount):
print(f"Paying ${amount} using Credit Card: {self.card_number}")
return True
class PayPalPayment(PaymentStrategy):
def __init__(self, email, password):
self.email = email
self.password = password
def pay(self, amount):
print(f"Paying ${amount} using PayPal account: {self.email}")
return True
class ShoppingCart:
def __init__(self):
self.items = []
self.payment_strategy = None
def add_item(self, item, price):
self.items.append({"item": item, "price": price})
def set_payment_strategy(self, payment_strategy):
self.payment_strategy = payment_strategy
def checkout(self):
total = sum(item["price"] for item in self.items)
if self.payment_strategy:
return self.payment_strategy.pay(total)
else:
raise ValueError("No payment strategy set")
# BitcoinPayment strateji sınıfınızı burada oluşturun
if __name__ == "__main__":
main()Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerself ParametresiMetotlarÖzniteliklerYapıcı Metot (__init__)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımsuper() FonksiyonuMetot Geçersiz KılmaÇoklu KalıtımMetot Çözümleme SırasıÖzet - Çalışan Hiyerarşisi7Özel Metotlar
Sihirli Metotlara GirişOperatör Aşırı YüklemeKapsayıcı Sihirli MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım kalıplarına girişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı13Final Meydan Okumaları
E-öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi5Çok Biçimlilik (Polymorphism)
Metot Geçersiz Kılmaya Yeniden BakışDuck TypingSoyut Sınıflar ve MetotlarArayüz TasarımıÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon ve KalıtımMixinsStatik ve Sınıf MetotlarıSınıf DekoratörleriBağlam Yöneticileri11Tasarı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ı