DDD به زبان ساده

پیچیدگی یک امر ذاتی در نرم‌افزار است؛ چون ذهن انسان ها پیچیده است، این امر طبیعی خواهد بود که ساختۀ ذهن آن‌ها نیز پیچیده باشد. پیچیدگی در نرم‌افزارها چندین منشا دارد؛ اما همۀ آن‌ها به صورت مسئله باز نمی‌گردند و در اصطلاح ذاتی نیستند. به این نوع از پیچیدگی که شامل نحوۀ حل مسئله و ابزارهای مورد استفاده برای دستیابی به آن است، پیچیدگی تصادفی گفته می‌شود. همانطور که میزان حجم یک نرم‌افزار افزایش پیدا می‌کند، پیچیدگی آن نیز اجتناب ناپذیرتر می‌شود و در اینصورت، سازماندهی و ساختاربندی کُد، از آنچه که در ابتدا درنظر گرفته شده بود، دشوارتر خواهد شد. چنین پدیده‌ای به‌عنوان آنتروپی نرم‌افزار شناخته می‌شود. اگر دستورالعمل‌های معماری در طول تکرارهای متعدد و توسعۀ نرم‌افزار اجرا نشوند، حفظ تعادل میان دغدغه‌های کاربران سیستم و جداسازی صحیح کلاس‌ها و ماژول‌ها، چالش‌برانگیزتر می‌شود.در معماری رایج Model View Controller) MVC)، لایۀ مدل، تمام منطق کسب‌وکار را در خود جای می‌دهد، اما قوانین روشنی در مورد چگونگی حفظ مرزهای مسئولیت مناسب ارائه نمی‌دهد. تابه‌حال چندین الگو برای حل این مشکل ارائه شده است، اما همچنان خطر نَشتِ منطق و مسئولیت بین اجزاء وجود دارد که با تکامل مدل، قابلیت نگهداری و پایداری دشوارتر می‌شود.از طرف دیگر، ارتباط با متخصصین کسب‌وکار، جمع‌آوری الزامات و اجماع بین تیم‌های فنی و غیرفنی برای طراحی و پیاده‌سازی صحیح سیستمی که یک مسئلۀ تجاری را حل می‌کند، یک فرایند تکراری ثابت است که در آن مفاهیم و موضوعات می‌توانند نادرست تفسیر شوند و در نهایت پروژه را از مسیر دستیابی به اهداف اصلی خارج کنند.طراحی دامنه محور (DDD) تلاش می‌کند تا با تطبیق نیروهای فنی و غیرفنی که در یک پروژه نرم‌افزاری با هم تلاقی دارند، این چالش‌ها را حل نموده و مجموعه‌ای از الگوها را پیشنهاد دهد که ساختن یک سیستم مطلوب را تسهیل می‌نمایند.طراحی دامنه محور چیست؟قبل از اینکه بخواهیم طراحی دامنه محور (DDD - Domain Driven Desgin) را تعریف کنیم، ابتدا باید بدانیم که «دامنه» چه مفهومی دارد؟ در این زمینه، دامنه را می‌توان بدین شکل تعریف نمود:حوزۀ خاصی از فعالیت یا دانش که مجموعه‌ای از الزامات، اصطلاحات و عملکردهای مشترک را تعریف می‌کند که منطق نرم‌افزار برای حل یک مشکل براساس آن کار می کند.طراحی دامنه محور در واقع رویکردی برای طراحی نرم‌افزار است که پیاده‌سازی سیستم را به یک مدل دائماً در حال تکامل می‌چسباند و جزئیات نامربوط مانند زبان‌های برنامه‌نویسی، فناوری‌های زیرساخت و غیره را کنار می‌گذارد. این رویکرد اولین بار در کتاب آقای اِریک اِوانز به نام طراحی دامنه محور: مقابله با پیچیدگی در قلب نرم‌افزار مطرح شد که مطالعۀ آن خالی از لطف نیست. آقای اِوانز در این کتاب به سه نظم در طراحی دامنه محور به‌صورت زیر اشاره می‌کند:روی دامنۀ اصلی و منطق دامنه تمرکز کنید.طرح‌های پیچیده را بر اساس مدل‌های دامنه قرار دهید.به منظور بهبود مدل برنامه و حل و فصل مشکلات مرتبط با دامنه، پیوسته با متخصصین دامنه همکاری کنید.اگر تاکنون مطالب بالا را به درستی درک نکرده‌اید یا کلمات به‌کار رفته در آن برای شما نامفهوم است، اصلاً نگران نباشد. در مبحث طراحی دامنه محور، عبارات متفاوت و مهمی استفاده می‌شوند که در ادامه به تشریح آن‌ها پرداخته خواهد شد. هرکدام از این عبارات، بخشی از طراحی دامنه محور را تشکیل می‌دهند.منطق دامنهمنطق دامنه در واقع هدف مدل‌سازی را نشان می‌دهد که معمولاً از آن به‌عنوان کسب‌وکار هم یاد می‌شود. به کمک منطق دامنه، نحوه ایجاد، ذخیره و اصلاح داده‌ها مشخص می‌شود.مدل دامنهمدل دامنه شامل ایده‌ها، دانش، داده‌ها، معیارها و اهدافی است که حول آن مسئله ایست که به‌دنیال حل آن هستیم. مدل دامنه شامل تمام قوانین و الگوهایی است که به تیم توسعه کمک می‌کند تا با منطق پیچیدۀ کسب‌وکار مقابله کنند.زیردامنهیک دامنه از چندین زیردامنه تشکیل شده است که به بخش‌های مختلف منطق کسب‌وکار اشاره دارد. به‌عنوان مثال، یک فروشگاه خرده‌فروشی آنلاین می‌تواند کاتالوگ محصول، موجودی کالا و تحویل را به‌عنوان زیردامنه خود داشته باشد.مفاهیم محدودشدههمانطور که پیاده‌سازی و توسعۀ نرم‌افزار در جریان تکرارهای متعدد تکامل و پیچیدگی سیستم به تدریج افزایش می‌یابد، حفظ کنترل می‌تواند چالش برانگیز باشد. بنابراین، یک استراتژی دقیق برای درک و کنترل سیستم‌های بزرگ، مهم و اساسی است. تجزیۀ مدل به مفاهیم محدود شده که با یکدیگر تعامل دارند، راهی موثر برای جلوگیری از مشکلات پیچیدگی است. می‌توان گفت که یک مفهوم محدود شده، مرزی مفهومی در اطراف بخش‌هایی از برنامه و یا پروژه از نظر دامنۀ کسب‌وکار، تیم‌های توسعه و کُد است. یک مفهوم محدود شده، مؤلفه‌ها و مفاهیم مرتبط را گروه‌بندی نموده و از ابهام اجتناب می‌کند؛ زیرا برخی از آن‌ها می‌توانند دارای معانی مشابه و بدون تفاوت آشکاری باشند. مثلاً، اگر مفهوم محدود شده را درنظر نگیریم، یک «حرف» می‌تواند به معنای دو چیز بسیار متفاوت باشد: 1) یکی از حروف الفبا؛ و 2) سخن گفتن انسان‌ها با یکدیگر. اما با تعیین مرز و زمینه، می توان این دو معنا را از یکدیگر تشخیص داد.زبان فراگیرزبان فراگیر نوعی متدولوژی است که به همان زبانی اشاره دارد که کارشناسان و توسعه‌دهندگان زمانی که می‌خواهند دامنه‌ای که روی آن کار می‌کنند را تشریح کنند، از آن استفاده می‌کنند. استفاده از یک زبان فراگیر، امری ضروری است زیرا پروژه‌ها درصورت مواجهه با مشکلات زبانی، می‌توانند مختل شوند و دلیلش آن است که متخصصان دامنه از اصطلاحات مخصوص به خود استفاده می‌کنند درحالیکه متخصصان فناوری از اصطلاحات خود برای صحبت در مورد دامنه استفاده می‌نمایند. بین اصطلاحات مورد استفاده در بحث‌های روزانه و اصطلاحات استفاده شده میان این دو گروه، یک شکاف وجود دارد. به همین دلیل، لازم است مجموعه‌ای از اصطلاحات تعریف شوند که همه از آن استفاده نمایند. به این مجموعه، زبان فراگیر گفته می‌شود.موجودیت‌هاموجودیت‌ها ترکیبی از داده‌ها و رفتار هستند؛ مانند یک کاربر یا یک محصول. موجودیت‌های دارای هستند اما نقاط داده را با رفتار نشان می‌دهند.اشیاء ارزش‌دار و گروه‌های انباشتهاشیاء ارزش‌دار ویژگی و صفات را به‌همراه خود دارند، اما نمی‌توانند به تنهایی وجود داشته باشند. به‌عنوان مثال، آدرس می‌تواند یک شئ ارزش‌دار باشد. سیستم‌های بزرگ و پیچیده دارای موجودیت‌ها و اشیاء ارزش‌دار بی‌شماری هستند. به همین دلیل است که مدل دامنه به نوعی نیازمند ساختار است. به کمک گروه‌های انباشته، مدیریت موجودیت‌ها و اشیاء ارزش‌دار، آسان‌تر است. گروه‌های انباشته، موجودیت‌ها و اشیاء ارزش‌دار را در گروه های منطقی قرار می‌دهد و نحوۀ ارتباط آن‌ها با یکدیگر را نشان می‌دهد.سرویس دامنهسرویس دامنه یک لایۀ اضافی است که دارای منطق دامنه هم هست. این بخشی از مدل دامنه است، درست مانند موجودیت‌ها و اشیاء ارزش‌دار. درعین‌حال، سرویس برنامه یک لایۀ دیگر است که حاوی منطق کسب‌وکار نیست. با این حال، در طراحی دامنه محور جهت هماهنگ کردن فعالیت برنامه در بالای مدل دامنه قرار گرفته می‌گیرد.مخزنالگوی مخزن مجموعه‌ای از نهادهای کسب‌وکار است که زیرساخت داده را ساده می‌کند. این مدل دامنه را از نگرانی‌های زیرساختی رها ساخته و مفهوم لایه‌بندی جداسازی نگرانی‌ها را اعمال می‌نماید.ساختار طراحی دامنه محوردر پاراگراف‌های قبلی، عبارات زیادی تشریح شدند که شاید تجسم نمودن آن‌ها در کنار یکدیگر کمی دشوار باشد. حالا تمامی این مفاهیم را در قالب یک مثال، تشریح خواهیم نمود. اگر یک فروشگاه آنلاین را درنظر بگیریم، دامنۀ کسب‌وکار، شامل پردازش یک سفارش است. وقتی مشتری می‌خواهد سفارشی بدهد، ابتدا باید محصولات را بررسی کند. سپس موارد مورد نظر خود را انتخاب می‌کند، سفارش را تایید می‌کند، نوع ارسال را انتخاب می‌کند و در نهایت پرداخت می‌کند. سپس برنامه، داده‌هایی را که مشتری ارائه می‌دهد پردازش می‌کند. بنابراین باتوجه به آنچه در شکل زیر آمده است، این برنامه از لایه‌های زیر تشکیل می‌شود:لایۀ محیط کاربری: اینجاست که مشتری می‌تواند تمام اطلاعات مورد نیاز برای سفارش را پیدا کند. در مورد فروشگاه آنلاین، محیط کاربری جایی است که محصولات قرار دارند. این لایه اطلاعات را به مشتری ارائه می‌دهد و اقدامات آن‌ها را تفسیر می‌کند.لایۀ برنامه: این لایه حاوی منطق کسب‌وکار نیست بلکه بخشی است که کاربر را از یک صفحه به صفحۀ رابط کاربری دیگر هدایت می‌کند و همچنین با لایه‌های برنامه‌های سیستم‌های دیگر تعامل دارد. این لایه می‌تواند اعتبارسنجی ساده‌ای را انجام دهد اما هیچ منطق یا دسترسی به داده مربوط به دامنه ندارد. هدف این لایه، سازماندهی و واگذاری اشیاء دامنه برای انجام کارشان است. علاوه بر این، لایۀ برنامه تنها لایه‌ای است که برای همۀ مفاهیم محدودشده قابل دسترسی است.لایۀ دامنه: مفاهیم حوزۀ کسب‌و‌کار در این لایه قرار می‌گیرند. این لایه تمام اطلاعات مربوط به پرونده و قوانین کسب‌وکار را دربردارد. این لایه جایی است که موجودیت‌ها در آن قرار می‌گیرند. همانطور که قبلاً اشاره شد، موجودیت‌ها ترکیبی از داده‌ها و رفتار هستند، مانند یک کاربر یا یک محصول.لایۀ زیرساخت: این لایه از ارتباط بین لایه‌های دیگر پشتیبانی می‌کند و می‌تواند شامل کتابخانه‌های پشتیبانی کننده برای لایۀ رابط کاربری باشد.حالا که با طراحی دامنه محور آشنا شدید، به معرفی مزایا و معایب آن خواهیم پرداخت. ابتدا با تشریح مزایای طراحی دامنه محور آغاز خواهیم نمود:ارتباطات را تسهیل می‌کند: با تأکید بر ایجاد یک زبان مشترک و مرتبط با مدل دامنۀ پروژه، تیم‌ها اغلب ارتباط در کل چرخۀ توسعه را بسیار آسان‌تر می‌بینند. به‌طور معمول، طراحی دامنه محور به هنگام بحث در مورد جنبه‌های برنامه به اصطلاحات فنی کمتری نیاز دارد، زیرا زبان فراگیر که در اوایل ایجاد شده، احتمالاً اصطلاحات ساده‌تری را برای اشاره به جنبه‌های فنی‌تر تعریف می‌کند.انعطاف پذیری را بهبود می‌بخشد: از آنجایی که طراحی دامنه محور به شدت بر روی مفاهیم تجزیه و تحلیل و طراحی شئ‌گرا استوار است، تقریباً همه چیز در مدل دامنه، مبتنی بر یک شئ است و بنابراین کاملاً مدولار و محصور می‌شود. این ویژگی به تیم توسعه اجازه می‌دهد تا اجزای مختلف، یا حتی کل سیستم به‌طور منظم و مداوم تغییر و بهبود یابد.بر روی اینتِرفِیس دامنه تاکید می‌کند: از آنجایی که طراحی دامنه محور برابرست با یک تمرین برای ایجاد مفاهیم برروی دامنه، اغلب برنامه‌هایی را تولید می‌کند که برخلاف برنامه‌هایی که UI/UX را در اولویت قرار می‌دهند، دقیقاً برای دامنۀ مورد نظر مناسب هستند. تمرکز بر دامنه به این معنی است که رویکرد طراحی دامنه محور می‌تواند محصولی تولید کند که به خوبی با مخاطبان مرتبط با آن دامنه همراه شود.اما هر رویکرد در دنیای نرم‌افزار، همراه با برخی معایب است. از جمله معایب رویکرد طراحی دامنه محور می‌توان به موارد زیر اشاره نمود:به تخصص قوی در دامنه نیاز دارد: حتی با وجود ماهرترین ذهن‌های فنی که روی توسعۀ نرم‌افزار کار می‌کنند، اگر حداقل یک متخصص دامنه در تیم وجود نداشته باشد که از جزئیات دقیق حوزۀ موضوعی که برنامه برای آن درنظر گرفته شده است مطلع نباشد، همه چیز بیهوده است. در برخی موارد، طراحی دامنه محور ممکن است به ادغام یک یا چند عضو خارجی تیم نیاز داشته باشد که می‌توانند به‌عنوان متخصص دامنه در طول چرخۀ توسعه عمل کنند.تکرار فرایند را تشویق می‌کند: درحالیکه بسیاری این ویژگی را یک مزیت می‌دانند، نمی‌توان انکار کرد که فرایندهای طراحی دامنه محور قویاً بر تکرار ثابت و یکپارچگی مداوم برای ساختن یک پروژه انعطاف‌پذیر است. برخی از سازمان‌ها ممکن است با این شیوه‌ها مشکل داشته باشند، به‌ویژه اگر تجربه گذشتۀ آن‌ها تا حد زیادی با مدل‌های توسعۀ کمتر انعطاف‌پذیر، مانند مدل آبشاری یا موارد مشابه مرتبط باشد.برای پروژه‌های بسیار فنی، مناسب نیست: درحالیکه طراحی دامنه محور برای برنامه‌هایی که پیچیدگی دامنۀ زیادی دارند (که منطق کسب‌وکار نسبتاً پیچیده است) عالی است، اما برای برنامه‌هایی که پیچیدگی فنی زیادی دارند، زیاد مناسب نیست. از آنجایی که طراحی دامنه محور به شدت بر نیاز (و اهمیت) متخصصان دامنه برای تولید زبان مناسب و سپس مدل دامنه ای که پروژه براساس آن استوار است تأکید می کند، پروژه‌ای که از نظر فنی فوق‌العاده پیچیده باشد، ممکن است برای کارشناسان دامنه چالش برانگیز بوده و مشکلات زیادی را ایجاد کند.سخن پایانیطراحی دامنه محور یک رویکرد مهندسی نرم‌افزار برای حل یک مدل دامنه خاص است که در این پست سعی شد تا مفاهیم کلی آن به زبانی ساده بیان شود. برای کسب اطلاعات در این زمینه پیشنهاد می‌شود که دو کتاب مرجع طراحی دامنه محور توسط اِریک اِوانز و پیاده‌سازی طراحی دامنه محور توسط وان وِرنون را مطالعه نمایید.همچنین اگر به مباحث پیاده‌سازی و عملی علاقه دارید، در گیت‌هاب نمونه‌های متعددی را می‌توان یافت که بسیار آموزنده بوده و به کمک آن‌ها می‌توان مفاهیم را بهتر درک نمود.این مطلب به‌عنوان پاسخ برای بخشی از تمرین‌های درس معماری نرم‌افزار در دانشگاه شهید بهشتی نوشته شده است که امیدوارم از آن استفاده برده باشید.مراجع[1] Banks, F. (2020, October 16). Domain-Driven Design: What is it and how do you use it? Airbrake. https://airbrake.io/blog/software-design/domain-driven-design [2] Evans, E. (2003). Domain-Driven Design: Tackling Complexity in the Heart of Software (1st ed.). Addison-Wesley Professional.[3] Evans, E. (2014). Domain-Driven Design Reference: Definitions and Pattern Summaries. Dog Ear Publishing.[4] Martinez, P. (2021, July 13). Domain-Driven Design: Everything You Always Wanted to Know | SSENSE-TECH. Medium. https://medium.com/ssense-tech/domain-driven-design-everything-you-always-wanted-to-know-about-it-but-were-afraid-to-ask-a85e7b74497a [5] Miteva, S. (2020, July 3). The Concept of Domain-Driven Design Explained - Microtica. Medium. https://medium.com/microtica/the-concept-of-domain-driven-design-explained-3184c0fd7c3f [6] V. (2020). GitHub - VaughnVernon/IDDD_Samples: These are the sample Bounded Contexts from the book “Implementing Domain-Driven Design” by Vaughn Vernon. GitHub. https://github.com/VaughnVernon/IDDD_Samples [7] Vernon, V. (2013). Implementing Domain-Driven Design (1st ed.). Addison-Wesley Professional.[8] Wikipedia contributors. (2021, November 22). Domain-driven design. Wikipedia.https://en.wikipedia.org/wiki/Domain-driven_design