آشنایی با Bounded Context

Subdomain های موجود در فضای مساله در فضای راه حل به Bounded Context تبدیل می شوند.

آشنایی با Bounded Context

در یک سیستم بزرگ و پیچیده پیاده سازی یک مدل برای پاسخگویی به تمام نیازها، در عمل امکان پذیر نمی باشد. شرکتی را در نظر بگیرید که قصد راه اندازی سیستم e-commerce آنلاین را دارد. از جمله بخش هایی که برای این سیستم در نظر گرفته شده است، بخش مدیریت کالاها در انبار، نمایش کاتالوگ محصولات، مدیریت سفارشات خرید، مدیریت تراکنش های مالی و مدیریت ارسال و رساندن محصولات به دست مشتری می باشد. سیستم فوق از چند Subdomain (زیر دامنه) تشکیل شده است که هر کدام یک جنبه از سیستم کلی را تشکیل می دهند. هر Subdomain زبان و مفاهیم مخصوص به خود را دارد. برای مثال یک “کالا” در انبار ممکن است در واقعیت با یک “محصول” در سیستم فروش یکی باشد، اما هر کدام در سیستم خود تعریف جداگانه و رفتارهای جداگانه ای دارند. هر Subdomain در حالت ایده آل در قالب یک Bounded Context به اختصار BC پیاده سازی می شود.

Subdomain

تقریبا Domain تمامی نرم افزارهای Enterprise از چندین Subdomain تشکیل شده است. شناخت Subdomain های سیستم شما را قادر می سازد تا Problem Space (فضای مساله) را به بخش های کوچک تر تقسیم کنید. بخش مشخصی از Domain که هدف اصلی توسعه ی سیستم و محصول اصلی می باشد با عنوان Core Domain  شناخته می شود. تمرکز اصلی در رویکرد DDD بر توسعه ی Core Domain می باشد. Subdomain هایی نیز در سیستم هستند که وجود آن ها الزامی است و بخشی از Business مخصوص به مشتری را پیاده سازی می کنند، اما بخشی از Core Domain نیستند. این Subdomain ها هدف اصلی ساخت سیستم نیستند اما به Core Domain در رسیدن به اهداف و کامل کردن سیستم کمک می کنند. Subdomain های فوق با نام Supporting Subdomains (زیر دامنه های حامی) شناخته می شوند. Subdomain هایی که هیچ پیاده سازی خاص منظوره ای از فرآیند های Business ندارند، اما وجود آن برای فعالیت سیستم الزامی است، با عنوان Generic Subdomains (زیردامنه های عمومی) شناخته می شوند.

مثالی از تحلیل Domain سیستم  e-commerce :

مفهوم Bounded Context

تصویر از کتاب Practicing Domain-Driven Design نوشته Scott Millett

 Supporting و یا Generic بودن یک Subdomain به معنای “بی اهمیت” بودن آن نیست. این Subdomain ها برای موفقیت Business مهم و الزامی هستند. اما تمرکز توسعه باید بر روی Core Domain و کیفیت آن باشد.

Bounded Context

Subdomain های موجود در فضای مساله (Problem Space)، در فضای راه حل (Solution Space) به Bounded Context تبدیل می شوند. در حالت ایده آل هر Subdomain در پیاده سازی به یک BC تبدیل می شود. هر BC یک واحد مستقل شناخته می شود و Domain Model مخصوص به خود را دارد. الگوهای طراحی و معماری در هر BC میتواند (بسته به ماهیت آن) متفاوت باشد. برای مثال ممکن است در پیاده سازی یک BC از معماری لایه ای معمول و در دیگری از الگوی CQRS استفاده کنیم :

مفهوم Bounded Context

تصویر از کتاب Practicing Domain-Driven Design نوشته Scott Millett

الزامی در وجود دیتابیس متفاوت به ازای هر BC وجود ندارد، بلکه BC ها می توانند همه از یک دیتابیس استفاده نمایند. BC ها در پیاده سازی در قالب بخش های جدا و مستقل (برای مثال DLL های جدا در NET.) توسعه می یابند :

مفهوم Bounded Context

Context Map

یک سیستم بزرگ می تواند BC های زیادی داشته باشد که این BC ها به شکل های مختلفی با هم در ارتباط هستند. Context Map مستندی است که روابط بین BC ها را مشخص می کند. Context Map به شما کمک می کند تا مرز های BC ها و نحوه ی تبادل و اشتراک داده بین آن ها را به وضوح مشخص کنید. مثالی از یک Context Map  و یکپارچه سازی فنی در آن :

مفهوم Bounded Context

تصویر از کتاب Practicing Domain-Driven Design نوشته Scott Millett

نحوه ارتباط BC ها با یکدیگر

همانطور که در پاراگراف قبل مطرح شد، BC ها برای تکمیل فرآیند های Business باید با یکدیگر در ارتباط باشند. DDD تعدادی الگو و روش برای برقراری ارتباط بین BC ها و یکپارچه سازی آنها دارد که در این مقاله به طور مختصر به بررسی برخی از آنها می پردازیم.

Anti-Corruption Layer به اختصار ACL

هنگام برقراری ارتباط Bounded Context ها با یکدیگر باید مطمئن شوید که مفاهیم یک Domain با دیگری درآمیخته نشود. به همین دلیل لایه ای جداگانه جهت برقراری ارتباط بین دو BC ایجاد می شود تا از بهم ریختگی مدل جلوگیری شود. لازم به ذکر است که این لایه تنها مسئول ترجمه کردن مفاهیم و مدل بین دو BC است و شامل هیچ فرآیندی از Business نمی باشد. ساختار یک ACL :

مفهوم Bounded Context

تصویر از کتاب Domain-Driven Design نوشته Eric Evans

Shared Kernel

هنگامی که دو تیم توسعه بر روی دو BC مختلف کار میکنند که از نظر منطق و فرآیندهای Domain همگذری زیادی دارند، جداسازی کار این دو تیم و نوشتن لایه های ارتباطی مانند ACL برای ترجمه ی مفاهیم بین این دو می تواند هزینه ی زیادی را در بر داشته باشد. در مواقع این چنینی بهترین کار به اشتراک گذاشتن قسمتی از مدل جهت آسان کردن فرآیند یکپارچه سازی و ارتباط بین دو BC است. این روش اغلب زمانی به کار می آید که یک Subdomain در قالب چند Bounded Context پیاده سازی می شود.

مفهوم Bounded Context

تصویر از کتاب Practicing Domain-Driven Design نوشته Scott Millett

باید توجه داشت هنگام استفاده از این روش، تغییرات نمی توانند آزادانه بر روی مدل مشترک اعمال شوند. زیرا هر تغییری ممکن است باعث به وجود آمدن مشکل در BC تیم دیگر شود. به همان دلیل تغییرات پس از مشاوره و پاس شدن تست های هر دو تیم در مدل مشترک اعمال می شوند.

Open Host Service

هنگامی که تعداد روابط یک BC با بقیه زیاد باشد و هر کدام از این روابط نیازمند نوشتن یک لایه ی جدا برای برقراری ارتباط باشد، میتوان یک دسته از سرویس های مشخص را تولید و در اختیار بقیه ی BC ها قرار داد. این سرویس ها می توانند در قالب سرویس های SOAP و یا سرویس های RESTful باشند :

مفهوم Bounded Context

تصویر از کتاب Practicing Domain-Driven Design نوشته Scott Millett

Publish-Subscribe

در این روش BC ها با ارسال Event به دیگران، آنها را از رخداد یک اتفاق در مدل خود آگاه میکنند. دیگران نیز با توجه به Event ارسال شده، تصمیمی اتخاذ کرده و فرآیندی را اجرا می کنند. باید توجه داشت ارسال کننده ی Event از وجود Subscriber ها و فرآیند های آنها اطلاعی ندارد. این روش ارتباط شما را قادر می سازد تا سیستم های مستقل از هم و در عین حال مرتبط با هم طراحی کنید. این مزیت باعث شده است که Domain Event ها تبدیل به یکی از اجزاء اصلی مدل شوند. استفاده از این الگو نیازمند پیاده سازی زیر ساختی جهت ارسال Event ها و همچنین Subscribe کردن به آنها است.

مفهوم Bounded Context

تصویر از کتاب Practicing Domain-Driven Design نوشته Scott Millett

مفهوم Bounded Context مفهوم Subdomain آموزش طراحی و معماری نرم افزار آشنایی با Domain Driven Design آموزشگاه برنامه نویسی