توی پایتون بجای isinstance از singledispatch استفاده کن!
۱. ابتدا دو کلاس با استفاده از
@dataclass
تعریف میکنیم:
@dataclass
class UserCanceledSubscription:
username: str
@dataclass
class UserSubscribed:
username: str
اینها دو نوع ایونت هستند: یکی برای زمانی که کاربر مشترک میشود و دیگری برای زمانی که اشتراکش را لغو میکند.
۲. روش اول با استفاده از
isinstance
:
def process(event):
if isinstance(event, UserSubscribed):
print(f"Enable access to user {event.username}")
elif isinstance(event, UserCanceledSubscription):
print(f"Disable access to user {event.username}")
در این روش، برای هر نوع رویداد یک شرط
if
نوشته شده که نوع رویداد را چک میکند.
۳. روش دوم با استفاده از
singledispatch
:
@singledispatch
def process(event):
pass
@process.register(UserCanceledSubscription)
def _(event):
print(f"Disable access to user {event.username}")
@process.register(UserSubscribed)
def _(event):
print(f"Enable access to user {event.username}")
در این روش، برای هر نوع رویداد یک تابع جداگانه تعریف میشود که فقط برای آن نوع خاص اجرا میشود.
مزایای استفاده از
singledispatch
:
۱.
کد تمیزتر: به جای زنجیرهای از `if/elif`، هر منطق در یک تابع جداگانه قرار میگیرد.
۲.
قابلیت توسعه بهتر: اضافه کردن نوع جدید فقط نیاز به اضافه کردن یک تابع جدید دارد، نه تغییر کد موجود.
۳.
جداسازی مسئولیتها: هر تابع فقط مسئول پردازش یک نوع خاص است.
۴.
کاهش پیچیدگی: به جای یک تابع بزرگ با شرطهای متعدد، چندین تابع کوچک و ساده داریم.
نحوه کار:
-
@singledispatch
یک تابع پایه تعریف میکند
-
@process.register()
توابع مختلف را برای انواع مختلف ورودی ثبت میکند
- در زمان اجرا، بر اساس نوع ورودی، تابع مناسب فراخوانی میشود
کاربرد این الگو در مواردی مثل:
- پردازش انواع مختلف پیامها یا رویدادها
- تبدیل دادهها بین فرمتهای مختلف
- اعمال عملیاتهای متفاوت روی انواع مختلف داده
- پیادهسازی الگوی Observer یا Event Handler
نمونه استفاده نهایی:
events = [
UserSubscribed(username="johndoe"),
UserCanceledSubscription(username="johndoe"),
]
for event in events:
process(event)
این کد به طور خودکار تابع مناسب را برای هر نوع رویداد فراخوانی میکند.
#python #singledispatch
@Syntax_fa