الگوی 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
✅ شرطهای تمیزتر در Python با
خیلی وقتها توی if ها چند شرط پشتسرهم با
ایده اصلی:
-
-
یک مثال واقعی: اعتبارسنجی ورودی کاربر 👇
بهجای چند if تو در تو، با یک
مرجع: Python docs - any & all
امتحان استفاده از
🔖 #Python #پایتون #Python #any #all #conditions #clean_code #validation #tips
👤 Developix
💎 Channel: @DevelopixPython
any و all 🧠خیلی وقتها توی if ها چند شرط پشتسرهم با
and و or مینویسیم و کد شلوغ میشود. دو تابع ساده و خیلی Pythonic برای تمیز کردن این شرطها داریم: any و all.ایده اصلی:
-
any(iterable) اگر حداقل یک مقدار True باشد، True برمیگرداند.-
all(iterable) فقط وقتی همه مقادیر True باشند، True برمیگرداند.یک مثال واقعی: اعتبارسنجی ورودی کاربر 👇
def is_valid_user(data: dict) -> bool:
required_keys = ["username", "email", "password"]
# همه فیلدها باید وجود داشته باشند و خالی نباشند
return all(
key in data and isinstance(data[key], str) and data[key].strip()
for key in required_keys
)
user = {"username": "ali", "email": "", "password": "123"}
print(is_valid_user(user)) # False
بهجای چند if تو در تو، با یک
all هم خوانایی بهتر میشود هم خطاهای منطقی کمتر میشود. برای چک کردن اینکه «حداقل یکی» برقرار باشد، از any استفاده میشود.مرجع: Python docs - any & all
امتحان استفاده از
any و all در شرطهای قدیمی کد، کدبیس را تمیزتر و قابلدرکتر میکند. 😉🔖 #Python #پایتون #Python #any #all #conditions #clean_code #validation #tips
👤 Developix
💎 Channel: @DevelopixPython
👍3