| کانال توسعه‌دهندگان پایتون |
7.12K subscribers
54 photos
2 videos
4 files
56 links
⭕️ کانال توسعه‌دهندگان پایتون دولوپیکس

💠 دولوپیکس | جامعه توسعه‌دهندگان ایرانی

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
الگوی Strategy: خداحافظ if-elif-elseهای غول‌آسا 🧠

یکی از 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