Menu
Coddy logo textTech

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.

challenge icon

Görev

Orta

Alışveriş sistemimiz için yeni bir BitcoinPayment stratejisi uygulayın.

Göreviniz şunları yapmaktır:

  1. 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
  2. Ş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()
quiz iconKendini test et

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