مدل‌های حجیم جنگو؟ اینجا یه روش مرتب‌تر و تمیزتر برای سازمان‌دهی منطق‌تون هست!


۰


معماری تمیزتر در جنگو با استفاده از Signals و مرزبندی ماژول‌ها

در هر پروژه‌ای با ساختار درست، تعریف واضح مرزهای ماژولی برای نگهداری آسان و مقیاس‌پذیری بسیار مهم است. منظور از «مرز ماژولی» جداسازی شفاف بین ماژول‌های مختلف و نحوه‌ی ارتباط آنها با یکدیگر است.

برای رسیدن به این هدف، هر ماژول باید یک رابط (interface) واضح برای ارتباط داشته باشد. این رابط مشخص می‌کند که دیگر ماژول‌ها چطور می‌توانند با آن ارتباط برقرار کنند و چه اطلاعاتی می‌توانند دریافت کنند. بیرون از این رابط، بقیه جزئیات باید خصوصی نگه داشته شوند.

مثال‌هایی از چنین مرزبندی‌هایی را می‌توانید در REST APIها ببینید. وقتی با APIهای خارجی کار می‌کنیم، یک لیست endpointها و احتمالاً webhookها در اختیار داریم. هر چه درون API است برای ما یک جعبه سیاه است و ما به API خارجی اعتماد می‌کنیم که بهترین عملکرد را داشته باشد.

این ساختار به تیم‌ها اجازه می‌دهد بدون نیاز به دانستن جزئیات داخلی ماژول‌های دیگر، روی ماژول خودشان کار کنند. این باعث می‌شود سرعت توسعه روی موضوعات مهم‌تر افزایش یابد.

بدون وجود این مرزها، نرم‌افزارها به هم گره‌خورده و فهم، تست و تغییر آنها دشوار می‌شود.

جنگو امکان تعریف اپلیکیشن‌های جداگانه را دارد که می‌توان آنها را به اندازه‌ای ماژول در نظر گرفت. اما همچنان تفکیک اثرات جانبی (side effects) نیازمند کار بیشتری است. اپلیکیشن‌ها معمولاً با هم مرتبط هستند و هر تیم یا اپلیکیشن باید از جزئیات داخلی دیگری باخبر باشد. اینجاست که Django signals وارد می‌شوند؛ روشی برای جداسازی منطق دامنه (domain logic) از اثرات جانبی.


Django Signals به عنوان مکانیزم ارسال پیام

برای اطلاع رسانی به ماژول‌های دیگر درباره‌ی آنچه در یک ماژول اتفاق افتاده، به روشی برای ارسال پیام نیاز داریم. راه‌های مختلفی وجود دارد؛ مثلاً استفاده از وب‌هوک‌ها یا ایمیل. البته هیچ‌کدام برای اعلان‌های همزمان (in-process) مناسب نیستند. اینجا است که signalsهای جنگو کاربرد پیدا می‌کنند.

نحوه کار signals ساده است. فرض کنید signals مثل یک ایستگاه رادیویی هستند—وقتی اتفاقی می‌افتد، هر ماژولی که «روی موج» باشد می‌تواند واکنش نشان دهد.

اینجا هم مشابه است؛ در یک ماژول عملی انجام می‌شود که می‌خواهیم نتیجه‌اش برای دیگران هم مشخص شود. در این لحظه یک سیگنال فعال می‌شود. ماژول دیگری که آن سیگنال را دریافت می‌کند (receiver) منتظر می‌ماند و وقتی سیگنال فعال شد، کد مربوطه اجرا می‌شود.


نمونه عملی

ما یک سیگنال تعریف می‌کنیم که در تابع مناسب فعال شود. در مثال ما، پس از پردازش یک webhook از سرویسی سوم، سیگنال فعال می‌شود.

1# modules/payments/signals.py
2
3# تعریف سیگنال
4payment_was_confirmed = Signal()

سپس در فایل مربوط به عملیات پرداخت:

1# modules/payments/actions.py
2
3from modules.payments.signals import payment_was_confirmed
4
5def stripe_webhook_handler():
6    # پرداخت با موفقیت انجام شده
7    # سیگنال را فعال کن
8    payment_was_confirmed.send_robust(sender=FooBar, payment=payment)

در ماژول دیگر، مثلاً ماژول صورتحساب (billing)، یک receiver تعریف می‌کنیم. دقت کنید که در اینجا ماژول billing به ماژول payments وابسته شده است. وقتی سیگنال فعال شود، تابع store_confirmed_payment_for_billing اجرا می‌گردد:

1# modules/billing/receivers.py
2
3from modules.payments.signals import payment_was_confirmed
4from django.dispatch import receiver
5
6@receiver(payment_was_confirmed)
7def store_confirmed_payment_for_billing(sender, **kwargs):
8    # انجام کاری مرتبط با صورتحساب
9    pass

با این روش، وابستگی بین دو ماژول به وضوح مشخص است. به‌علاوه می‌توانیم چندین receiver در ماژول‌های مختلف داشته باشیم که باعث تسهیل توسعه قابلیت‌های جدید می‌شود.


مزایای استفاده از signals برای جداسازی

یکی از مزایای signals این است که در جنگو به صورت پیش‌فرض وجود دارند و برای شروع کار زیاد نیاز به یادگیری ندارید. نه نیازی به تعریف سیستم اختصاصی است و نه ابزار اضافی!

  • signals یک مرز ارتباطی شفاف ایجاد می‌کنند که ماژول‌های خارجی می‌توانند مشترک (subscribe) به سیگنال‌های خاص شوند.
  • امکان افزودن چندین receiver به یک سیگنال هست که توسعه کد را آسان‌تر می‌کند.
  • این کار تست منطق دامنه و هماهنگی (orchestration) را به صورت مستقل ساده‌تر می‌کند.

نتیجه‌گیری

مرزها برای هر اپلیکیشنی حیاتی‌اند و نحوه پیاده‌سازی آنها بسیار مهم است. با وجود signals در جنگو، هیچ دلیلی برای نداشتن مرزهای سخت وجود ندارد. وقتی مرزها به درستی اعمال شوند، می‌توانیم سریع‌تر حرکت کنیم و همکاری بین تیم‌ها راحت‌تر خواهد شد.

البته هیچ چیز رایگانی وجود ندارد! مرزها باید به‌خوبی تعریف و رعایت شوند که این موضوع خارج از محدوده این مطلب است. همچنین signals چالش‌هایی مثل سختی اشکال‌زدایی (debugging) و حالت همزمان بودن دارند، اما در شرایط مناسب، ابزار مفیدی برای ساخت مرز محسوب می‌شوند.

این مقاله اولین قسمت از یک سری کوتاه است که مثال‌هایی از استفاده signals برای تحکیم مرزها و محدود کردن منطق به جای درستش را نشان می‌دهد. اگر تا به حال وسوسه شده‌اید که از یکی از لایه‌ها عبور کنید و «فقط یک متد را صدا بزنید» — این مقاله مخصوص شماست.

جنگو
پایتون

۰


نظرات


author
نویسنده مقاله: حامد فیض آبادی

کد با می متعهد است که بالاترین سطح کیفی آموزش را در اختیار شما بگذارد. هدف به اشتراک گذاشتن دانش فناوری اطلاعات و توسعه نرم افزار در بالاترین سطح ممکن برای درستیابی به جامعه ای توانمند و قدرتمند است. ما باور داریم هر کسی میتواند با استمرار در یادگیری برنامه نویسی چالش های خود و جهان پیرامون خود را بر طرف کند و به موفقیت های چشم گیر برسد. با ما در این مسیر همراه باشید. کد با می اجتماع حرفه ای برنامه نویسان ایرانی.

تمام حقوق این سایت متعلق به وبسایتcodebymeمیباشد.