תבנית Strategy
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Python של Coddy. שיעור 48 מתוך 64.
תבנית האסטרטגיה מגדירה משפחה של אלגוריתמים, עוטפת כל אחד מהם והופכת אותם לניתנים להחלפה. אפשר להחליף אלגוריתמים בזמן ריצה בלי לשנות את קוד הלקוח.
הנה מחלקות אסטרטגיה פשוטות לשיטות תשלום שונות:
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"כל אסטרטגיה מממשת את אותה השיטה (pay), אך עם התנהגות שונה.
צרו מחלקת הקשר שמשתמשת באסטרטגיות:
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)מחלקת ההקשר יכולה לעבור בין אסטרטגיות תשלום שונות.
השתמשו בתבנית האסטרטגיה:
cart = ShoppingCart()
cart.add_item(50)
cart.add_item(30)
# השתמש באסטרטגיית תשלום בכרטיס אשראי
cart.set_payment_strategy(CreditCard())
print(cart.checkout())
# עבור לאסטרטגיית PayPal
cart.set_payment_strategy(PayPal())
print(cart.checkout())צרו דוגמה נוספת עם אסטרטגיות מיון:
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)
# השתמשו באסטרטגיות מיון שונות
numbers = [3, 1, 4, 1, 5]
sorter = Sorter(BubbleSort())
print(sorter.sort_data(numbers))
sorter.set_strategy(QuickSort())
print(sorter.sort_data(numbers))פלט:
Paid $80 with Credit Card
Paid $80 with PayPal
Bubble sorted: [1, 1, 3, 4, 5]
Quick sorted: [1, 1, 3, 4, 5]נקודה מרכזית: תבנית האסטרטגיה מאפשרת להחליף אלגוריתמים בזמן ריצה. מגדירים אסטרטגיות שונות עם אותו ממשק, ואז מאפשרים למחלקת ההקשר לבחור באיזו אסטרטגיה להשתמש. כך הקוד שלך גמיש וקל להרחבה באמצעות אלגוריתמים חדשים, בלי לשנות קוד קיים.
אתגר
בינוניממשו אסטרטגיית BitcoinPayment חדשה עבור מערכת הקניות שלנו.
המשימה שלכם:
- ליצור מחלקה בשם BitcoinPayment שמממשת את PaymentStrategy
- המחלקה צריכה לקבל wallet_address בבנאי
- המתודה pay צריכה להדפיס בדיוק:
Paying $X using Bitcoin wallet: Yכאשר X הוא הסכום ו-Y היא כתובת הארנק - המתודה pay צריכה להחזיר True לאחר ההדפסה
- לכתוב פונקציה בשם main ש:
- יוצרת עגלת קניות
- מוסיפה לעגלה מחשב נייד שעולה $1200 ואוזניות שעולות $100
- יוצרת BitcoinPayment עם כתובת הארנק "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
- מגדירה את אסטרטגיית התשלום הזו בעגלה
- קוראת למתודה checkout
קוד הפתיחה כבר כולל את if __name__ == "__main__": בתחתית. אין צורך להוסיף אותו בעצמכם. זו מוסכמה של Python שמבטיחה שהפונקציה main() תפעל רק כשהקובץ מופעל ישירות (ולא כשהוא מיובא על ידי מודול אחר). פשוט הגדירו את הפונקציה main(), והבלוק שסופק יקרא לה באופן אוטומטי.
פעלו לפי אותו מבנה שמוצג בדוגמאות השיעור.
נסו בעצמכם
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
if __name__ == "__main__":
main()השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים (OOP)
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםהפרמטר selfמתודותמאפייניםשיטת הבנאי (__init__)חזרה: מחשבון פשוט5פולימורפיזם
בחינה מחדש של דריסת מתודותטיפוסיות ברווזמחלקות ומתודות אבסטרקטיותעיצוב ממשקיםסיכום – מחשבון צורות8מושגים מתקדמים בתכנות מונחה עצמים
קומפוזיציה לעומת הורשהMixinsמתודות סטטיות ומתודות מחלקהדקורטורים למחלקותמנהלי הקשרתרגלו בעצמכם: קומפיילר Python אונליין