Strategy-Muster
Teil des Abschnitts Objektorientierte Programmierung der Python-Journey von Coddy. Lektion 48 von 64.
Das Strategy Pattern 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)
# Kreditkarten-Strategie 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)
# Verwende verschiedene Sortierstrategien
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]Wichtiger Punkt: Das Strategiemuster ermöglicht es dir, Algorithmen zur Laufzeit auszutauschen. 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 einfach um neue Algorithmen erweitern, ohne bestehenden Code zu ändern.
Aufgabe
MittelImplementiere eine neue BitcoinPayment-Strategie für unser Einkaufssystem.
Deine Aufgabe ist:
- Erstelle eine BitcoinPayment-Klasse, die PaymentStrategy implementiert
- Sie sollte im Konstruktor eine wallet_address akzeptieren
- Die pay-Methode sollte genau 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
- Schreibe eine main-Funktion, die:
- einen Einkaufswagen erstellt
- einen Laptop im Wert von $1200 und Kopfhörer im Wert von $100 in den Einkaufswagen legt
- eine BitcoinPayment mit der Wallet-Adresse "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa" erstellt
- diese Zahlungsstrategie für den Einkaufswagen festlegt
- die checkout-Methode aufruft
Der Ausgangscode enthält bereits if __name__ == "__main__": am Ende. Du musst ihn 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 wird sie automatisch aufrufen.
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")
# Create your BitcoinPayment strategy class here
if __name__ == "__main__":
main()Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDer self-ParameterMethodenAttributeKonstruktormethode (__init__)Zusammenfassung – Einfacher Taschenrechner4Vererbung
Grundlegende VererbungDie super()-FunktionMethodenüberschreibungMehrfachvererbungMethodenauflösungsreihenfolgeWiederholung – Mitarbeiterhierarchie7Spezielle Methoden
Einführung in magische MethodenOperatorüberladungMagische Methoden für ContainerRückblick – Benutzerdefinierte Liste10Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster13Abschließende Herausforderungen
E-Learning-PlattformBankensystemEntwicklung von SpielfigurenFahrzeugvermietungsservice2Dekoratoren
Einführung in DekoratorenProperty-DekoratorDekorator für statische MethodenDekorator für Klassenmethoden5Polymorphie
Methodenüberschreibung erneut betrachtetDuck-TypingAbstrakte Klassen und MethodenSchnittstellendesignRückblick – Formrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungMixinsStatische Methoden und KlassenmethodenKlassen-DekoratorenKontextmanager3Klassenattribute
Instanz- vs. KlassenvariablenProperty-DecoratorsPrivate AttributeWiederholung – Bankkontoverwaltung6Kapselung
Öffentliche, geschützte, private MemberZugriffsmodifikatorenInformationsverbergungProperty-Decorators – FortgeschrittenWiederholung – System zur Verwaltung von Studentendaten12Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und BenutzerklassenAusleihsystemSuchfunktionAdministrationsoberflächeTests und IntegrationÜbe selbstständig: Online-Python-Compiler