Menu
CoddyTech

Strategy-Muster

Teil des Abschnitts Objektorientierte Programmierung der Python-Journey von Coddy. Lektion 48 von 64.

Das Strategy-Muster definiert eine Familie von Algorithmen, kapselt jeden einzelnen und macht sie austauschbar. Du kannst Algorithmen zur Laufzeit wechseln, ohne den Client-Code zu ändern.

Hier sind einfache Strategienklassen für verschiedene Zahlungsmethoden:

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"

Jede Strategie implementiert dieselbe Methode (pay), aber mit unterschiedlichem Verhalten.

Erstelle eine Kontextklasse, die Strategien verwendet:

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)

Die Kontextklasse kann zwischen verschiedenen Zahlungsstrategien wechseln.

Verwende das Strategiemuster:

cart = ShoppingCart()
cart.add_item(50)
cart.add_item(30)

# Kreditkartenstrategie verwenden
cart.set_payment_strategy(CreditCard())
print(cart.checkout())

# Zur PayPal-Strategie wechseln
cart.set_payment_strategy(PayPal())
print(cart.checkout())

Erstelle ein weiteres Beispiel mit Sortierstrategien:

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)

# Verschiedene Sortierstrategien verwenden
numbers = [3, 1, 4, 1, 5]

sorter = Sorter(BubbleSort())
print(sorter.sort_data(numbers))

sorter.set_strategy(QuickSort())
print(sorter.sort_data(numbers))

Ausgabe:

Paid $80 with Credit Card
Paid $80 with PayPal
Bubble sorted: [1, 1, 3, 4, 5]
Quick sorted: [1, 1, 3, 4, 5]

Kernaussage: Mit dem Strategie-Muster kannst du Algorithmen zur Laufzeit austauschen. Definiere verschiedene Strategien mit derselben Schnittstelle und lass dann die Kontextklasse auswählen, welche davon verwendet werden soll. Dadurch wird dein Code flexibel und lässt sich leicht um neue Algorithmen erweitern, ohne den vorhandenen Code zu ändern.

challenge icon

Aufgabe

Mittel

Implementiere eine neue BitcoinPayment-Strategie für unser Einkaufssystem.

Deine Aufgabe ist:

  1. Erstelle eine BitcoinPayment-Klasse, die PaymentStrategy implementiert
    • Sie sollte im Konstruktor eine wallet_address entgegennehmen
    • Die pay-Methode sollte exakt Folgendes ausgeben: Paying $X using Bitcoin wallet: Y, wobei X der Betrag und Y die Wallet-Adresse ist
    • Die pay-Methode sollte nach der Ausgabe True zurückgeben
  2. Schreibe eine main-Funktion, die:
    • einen Einkaufswagen erstellt
    • dem Einkaufswagen einen Laptop für $1200 und Kopfhörer für $100 hinzufügt
    • eine BitcoinPayment-Instanz mit der Wallet-Adresse "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa" erstellt
    • diese Zahlungsstrategie für den Einkaufswagen festlegt
    • die checkout-Methode aufruft

Der vorgegebene Code enthält bereits if __name__ == "__main__": am Ende. Du musst es nicht selbst hinzufügen. Dies ist eine Python-Konvention, die sicherstellt, dass deine main()-Funktion nur ausgeführt wird, wenn die Datei direkt ausgeführt wird (nicht, wenn sie von einem anderen Modul importiert wird). Definiere einfach deine main()-Funktion, und der bereitgestellte Block ruft sie automatisch auf.

Halte dich an dieselbe Struktur wie in den Beispielen der Lektion.

Probier es selbst

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")

# Erstelle hier deine Strategieklasse BitcoinPayment


if __name__ == "__main__":
    main()
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Python-Compiler