الگوی Strategy: خداحافظ if-elif-elseهای غولآسا 🧠
یکی از Code Smellهای رایج در پروژههای Python، بهخصوص در Django / FastAPI، زنجیرههای بزرگ if / elif برای انتخاب نوع رفتار است. این ساختارها هم سخت تست میشوند، هم هر تغییر کوچکی را پرریسک میکنند.
یک راهحل تمیز و شناختهشده در Design Patternها برای این مشکل، الگوی Strategy است. این الگو منطقهای قابلجایگزین (قابل تعویض) را در آبجکتهای جدا نگه میدارد و کد را قابلگسترش و خواناتر میکند. 🙌
مثال ساده: فرض کنید در یک سرویس پرداخت، بسته به نوع روش پرداخت، منطق متفاوتی دارید:
این کلاس هم تکمسئولیتی نیست، هم هر بار روش جدیدی اضافه میشود باید کلاس را ادیت کنیم. زیر پا گذاشتن اصل Open/Closed.
با Strategy همین منطق را تمیز میکنیم:
حالا انتخاب Strategy میتواند در لایهی وب (مثلاً FastAPI endpoint) انجام شود و PaymentService تمیز و قابلتست میماند:
نکته عملی قابلاستفاده امروز ✅
هرجا یک تابع یا view دارید که براساس یک نوع (type / method / status) با if-elifهای زیاد شاخهبندی میکند، آن منطق را به کلاسهای کوچکتر Strategy تبدیل کنید و یک mapping تمیز بسازید. این کار هم خوانایی را بالا میبرد، هم اضافهکردن رفتار جدید را بدون دستزدن به منطق قدیمی ممکن میکند.
برای مطالعهی عمیقتر درباره Strategy:
refactoring.guru/design-patterns/strategy
کد تمیز با الگوهای درست، در پروژههای واقعی Python تفاوت جدی در سرعت توسعه و لذت کار ایجاد میکند. 🚀 امروز یکی از if-elifهای سنگین پروژهتان را به یک Strategy تمیز تبدیل کنید و نتیجه را در نگهداری و تستها ببینید.
🔖 #Python #پایتون #python #strategy_pattern #clean_code #design_patterns #architecture #refactoring
👤 Developix
💎 Channel: @DevelopixPython
یکی از Code Smellهای رایج در پروژههای Python، بهخصوص در Django / FastAPI، زنجیرههای بزرگ if / elif برای انتخاب نوع رفتار است. این ساختارها هم سخت تست میشوند، هم هر تغییر کوچکی را پرریسک میکنند.
یک راهحل تمیز و شناختهشده در Design Patternها برای این مشکل، الگوی Strategy است. این الگو منطقهای قابلجایگزین (قابل تعویض) را در آبجکتهای جدا نگه میدارد و کد را قابلگسترش و خواناتر میکند. 🙌
مثال ساده: فرض کنید در یک سرویس پرداخت، بسته به نوع روش پرداخت، منطق متفاوتی دارید:
class PaymentService:
def pay(self, method: str, amount: int) -> None:
if method == "card":
print("Paying by card", amount)
elif method == "paypal":
print("Paying by PayPal", amount)
elif method == "crypto":
print("Paying by crypto", amount)
else:
raise ValueError("Unsupported method")
این کلاس هم تکمسئولیتی نیست، هم هر بار روش جدیدی اضافه میشود باید کلاس را ادیت کنیم. زیر پا گذاشتن اصل Open/Closed.
با Strategy همین منطق را تمیز میکنیم:
from abc import ABC, abstractmethod
class PaymentStrategy(ABC):
@abstractmethod
def pay(self, amount: int) -> None:
...
class CardPayment(PaymentStrategy):
def pay(self, amount: int) -> None:
print("Paying by card", amount)
class PaypalPayment(PaymentStrategy):
def pay(self, amount: int) -> None:
print("Paying by PayPal", amount)
class CryptoPayment(PaymentStrategy):
def pay(self, amount: int) -> None:
print("Paying by crypto", amount)
class PaymentService:
def __init__(self, strategy: PaymentStrategy) -> None:
self._strategy = strategy
def pay(self, amount: int) -> None:
self._strategy.pay(amount)
حالا انتخاب Strategy میتواند در لایهی وب (مثلاً FastAPI endpoint) انجام شود و PaymentService تمیز و قابلتست میماند:
def get_strategy(method: str) -> PaymentStrategy:
mapping = {
"card": CardPayment(),
"paypal": PaypalPayment(),
"crypto": CryptoPayment(),
}
try:
return mapping[method]
except KeyError:
raise ValueError("Unsupported method")
نکته عملی قابلاستفاده امروز ✅
هرجا یک تابع یا view دارید که براساس یک نوع (type / method / status) با if-elifهای زیاد شاخهبندی میکند، آن منطق را به کلاسهای کوچکتر Strategy تبدیل کنید و یک mapping تمیز بسازید. این کار هم خوانایی را بالا میبرد، هم اضافهکردن رفتار جدید را بدون دستزدن به منطق قدیمی ممکن میکند.
برای مطالعهی عمیقتر درباره Strategy:
refactoring.guru/design-patterns/strategy
کد تمیز با الگوهای درست، در پروژههای واقعی Python تفاوت جدی در سرعت توسعه و لذت کار ایجاد میکند. 🚀 امروز یکی از if-elifهای سنگین پروژهتان را به یک Strategy تمیز تبدیل کنید و نتیجه را در نگهداری و تستها ببینید.
🔖 #Python #پایتون #python #strategy_pattern #clean_code #design_patterns #architecture #refactoring
👤 Developix
💎 Channel: @DevelopixPython
❤7👎2