پیچیدگی یک امر ذاتی در نرمافزار است؛ چون ذهن انسان ها پیچیده است، این امر طبیعی خواهد بود که ساختۀ ذهن آنها نیز پیچیده باشد. پیچیدگی در نرمافزارها چندین منشا دارد؛ اما همۀ آنها به صورت مسئله باز نمیگردند و در اصطلاح ذاتی نیستند. به این نوع از پیچیدگی که شامل نحوۀ حل مسئله و ابزارهای مورد استفاده برای دستیابی به آن است، پیچیدگی تصادفی گفته میشود. همانطور که میزان حجم یک نرمافزار افزایش پیدا میکند، پیچیدگی آن نیز اجتناب ناپذیرتر میشود و در اینصورت، سازماندهی و ساختاربندی کُد، از آنچه که در ابتدا درنظر گرفته شده بود، دشوارتر خواهد شد. چنین پدیدهای بهعنوان آنتروپی نرمافزار شناخته میشود. اگر دستورالعملهای معماری در طول تکرارهای متعدد و توسعۀ نرمافزار اجرا نشوند، حفظ تعادل میان دغدغههای کاربران سیستم و جداسازی صحیح کلاسها و ماژولها، چالشبرانگیزتر میشود.
در معماری رایج Model View Controller) MVC)، لایۀ مدل، تمام منطق کسبوکار را در خود جای میدهد، اما قوانین روشنی در مورد چگونگی حفظ مرزهای مسئولیت مناسب ارائه نمیدهد. تابهحال چندین الگو برای حل این مشکل ارائه شده است، اما همچنان خطر نَشتِ منطق و مسئولیت بین اجزاء وجود دارد که با تکامل مدل، قابلیت نگهداری و پایداری دشوارتر میشود.
از طرف دیگر، ارتباط با متخصصین کسبوکار، جمعآوری الزامات و اجماع بین تیمهای فنی و غیرفنی برای طراحی و پیادهسازی صحیح سیستمی که یک مسئلۀ تجاری را حل میکند، یک فرایند تکراری ثابت است که در آن مفاهیم و موضوعات میتوانند نادرست تفسیر شوند و در نهایت پروژه را از مسیر دستیابی به اهداف اصلی خارج کنند.
طراحی دامنه محور (DDD) تلاش میکند تا با تطبیق نیروهای فنی و غیرفنی که در یک پروژه نرمافزاری با هم تلاقی دارند، این چالشها را حل نموده و مجموعهای از الگوها را پیشنهاد دهد که ساختن یک سیستم مطلوب را تسهیل مینمایند.
قبل از اینکه بخواهیم طراحی دامنه محور (DDD - Domain Driven Desgin) را تعریف کنیم، ابتدا باید بدانیم که «دامنه» چه مفهومی دارد؟ در این زمینه، دامنه را میتوان بدین شکل تعریف نمود:
حوزۀ خاصی از فعالیت یا دانش که مجموعهای از الزامات، اصطلاحات و عملکردهای مشترک را تعریف میکند که منطق نرمافزار برای حل یک مشکل براساس آن کار می کند.
طراحی دامنه محور در واقع رویکردی برای طراحی نرمافزار است که پیادهسازی سیستم را به یک مدل دائماً در حال تکامل میچسباند و جزئیات نامربوط مانند زبانهای برنامهنویسی، فناوریهای زیرساخت و غیره را کنار میگذارد. این رویکرد اولین بار در کتاب آقای اِریک اِوانز به نام طراحی دامنه محور: مقابله با پیچیدگی در قلب نرمافزار مطرح شد که مطالعۀ آن خالی از لطف نیست. آقای اِوانز در این کتاب به سه نظم در طراحی دامنه محور بهصورت زیر اشاره میکند:
اگر تاکنون مطالب بالا را به درستی درک نکردهاید یا کلمات بهکار رفته در آن برای شما نامفهوم است، اصلاً نگران نباشد. در مبحث طراحی دامنه محور، عبارات متفاوت و مهمی استفاده میشوند که در ادامه به تشریح آنها پرداخته خواهد شد. هرکدام از این عبارات، بخشی از طراحی دامنه محور را تشکیل میدهند.
منطق دامنه در واقع هدف مدلسازی را نشان میدهد که معمولاً از آن بهعنوان کسبوکار هم یاد میشود. به کمک منطق دامنه، نحوه ایجاد، ذخیره و اصلاح دادهها مشخص میشود.
مدل دامنه شامل ایدهها، دانش، دادهها، معیارها و اهدافی است که حول آن مسئله ایست که بهدنیال حل آن هستیم. مدل دامنه شامل تمام قوانین و الگوهایی است که به تیم توسعه کمک میکند تا با منطق پیچیدۀ کسبوکار مقابله کنند.
یک دامنه از چندین زیردامنه تشکیل شده است که به بخشهای مختلف منطق کسبوکار اشاره دارد. بهعنوان مثال، یک فروشگاه خردهفروشی آنلاین میتواند کاتالوگ محصول، موجودی کالا و تحویل را بهعنوان زیردامنه خود داشته باشد.
همانطور که پیادهسازی و توسعۀ نرمافزار در جریان تکرارهای متعدد تکامل و پیچیدگی سیستم به تدریج افزایش مییابد، حفظ کنترل میتواند چالش برانگیز باشد. بنابراین، یک استراتژی دقیق برای درک و کنترل سیستمهای بزرگ، مهم و اساسی است. تجزیۀ مدل به مفاهیم محدود شده که با یکدیگر تعامل دارند، راهی موثر برای جلوگیری از مشکلات پیچیدگی است. میتوان گفت که یک مفهوم محدود شده، مرزی مفهومی در اطراف بخشهایی از برنامه و یا پروژه از نظر دامنۀ کسبوکار، تیمهای توسعه و کُد است. یک مفهوم محدود شده، مؤلفهها و مفاهیم مرتبط را گروهبندی نموده و از ابهام اجتناب میکند؛ زیرا برخی از آنها میتوانند دارای معانی مشابه و بدون تفاوت آشکاری باشند. مثلاً، اگر مفهوم محدود شده را درنظر نگیریم، یک «حرف» میتواند به معنای دو چیز بسیار متفاوت باشد: 1) یکی از حروف الفبا؛ و 2) سخن گفتن انسانها با یکدیگر. اما با تعیین مرز و زمینه، می توان این دو معنا را از یکدیگر تشخیص داد.
زبان فراگیر نوعی متدولوژی است که به همان زبانی اشاره دارد که کارشناسان و توسعهدهندگان زمانی که میخواهند دامنهای که روی آن کار میکنند را تشریح کنند، از آن استفاده میکنند. استفاده از یک زبان فراگیر، امری ضروری است زیرا پروژهها درصورت مواجهه با مشکلات زبانی، میتوانند مختل شوند و دلیلش آن است که متخصصان دامنه از اصطلاحات مخصوص به خود استفاده میکنند درحالیکه متخصصان فناوری از اصطلاحات خود برای صحبت در مورد دامنه استفاده مینمایند. بین اصطلاحات مورد استفاده در بحثهای روزانه و اصطلاحات استفاده شده میان این دو گروه، یک شکاف وجود دارد. به همین دلیل، لازم است مجموعهای از اصطلاحات تعریف شوند که همه از آن استفاده نمایند. به این مجموعه، زبان فراگیر گفته میشود.
موجودیتها ترکیبی از دادهها و رفتار هستند؛ مانند یک کاربر یا یک محصول. موجودیتهای دارای هستند اما نقاط داده را با رفتار نشان میدهند.
اشیاء ارزشدار ویژگی و صفات را بههمراه خود دارند، اما نمیتوانند به تنهایی وجود داشته باشند. بهعنوان مثال، آدرس میتواند یک شئ ارزشدار باشد. سیستمهای بزرگ و پیچیده دارای موجودیتها و اشیاء ارزشدار بیشماری هستند. به همین دلیل است که مدل دامنه به نوعی نیازمند ساختار است. به کمک گروههای انباشته، مدیریت موجودیتها و اشیاء ارزشدار، آسانتر است. گروههای انباشته، موجودیتها و اشیاء ارزشدار را در گروه های منطقی قرار میدهد و نحوۀ ارتباط آنها با یکدیگر را نشان میدهد.
سرویس دامنه یک لایۀ اضافی است که دارای منطق دامنه هم هست. این بخشی از مدل دامنه است، درست مانند موجودیتها و اشیاء ارزشدار. درعینحال، سرویس برنامه یک لایۀ دیگر است که حاوی منطق کسبوکار نیست. با این حال، در طراحی دامنه محور جهت هماهنگ کردن فعالیت برنامه در بالای مدل دامنه قرار گرفته میگیرد.
الگوی مخزن مجموعهای از نهادهای کسبوکار است که زیرساخت داده را ساده میکند. این مدل دامنه را از نگرانیهای زیرساختی رها ساخته و مفهوم لایهبندی جداسازی نگرانیها را اعمال مینماید.
در پاراگرافهای قبلی، عبارات زیادی تشریح شدند که شاید تجسم نمودن آنها در کنار یکدیگر کمی دشوار باشد. حالا تمامی این مفاهیم را در قالب یک مثال، تشریح خواهیم نمود. اگر یک فروشگاه آنلاین را درنظر بگیریم، دامنۀ کسبوکار، شامل پردازش یک سفارش است. وقتی مشتری میخواهد سفارشی بدهد، ابتدا باید محصولات را بررسی کند. سپس موارد مورد نظر خود را انتخاب میکند، سفارش را تایید میکند، نوع ارسال را انتخاب میکند و در نهایت پرداخت میکند. سپس برنامه، دادههایی را که مشتری ارائه میدهد پردازش میکند. بنابراین باتوجه به آنچه در شکل زیر آمده است، این برنامه از لایههای زیر تشکیل میشود:
حالا که با طراحی دامنه محور آشنا شدید، به معرفی مزایا و معایب آن خواهیم پرداخت. ابتدا با تشریح مزایای طراحی دامنه محور آغاز خواهیم نمود:
اما هر رویکرد در دنیای نرمافزار، همراه با برخی معایب است. از جمله معایب رویکرد طراحی دامنه محور میتوان به موارد زیر اشاره نمود:
طراحی دامنه محور یک رویکرد مهندسی نرمافزار برای حل یک مدل دامنه خاص است که در این پست سعی شد تا مفاهیم کلی آن به زبانی ساده بیان شود. برای کسب اطلاعات در این زمینه پیشنهاد میشود که دو کتاب مرجع طراحی دامنه محور توسط اِریک اِوانز و پیادهسازی طراحی دامنه محور توسط وان وِرنون را مطالعه نمایید.
همچنین اگر به مباحث پیادهسازی و عملی علاقه دارید، در گیتهاب نمونههای متعددی را میتوان یافت که بسیار آموزنده بوده و به کمک آنها میتوان مفاهیم را بهتر درک نمود.
این مطلب بهعنوان پاسخ برای بخشی از تمرینهای درس معماری نرمافزار در دانشگاه شهید بهشتی نوشته شده است که امیدوارم از آن استفاده برده باشید.
[1] Banks, F. (2020, October 16). Domain-Driven Design: What is it and how do you use it? Airbrake.
[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.
[5] Miteva, S. (2020, July 3). The Concept of Domain-Driven Design Explained - Microtica. Medium.
[6] V. (2020). GitHub - VaughnVernon/IDDD_Samples: These are the sample Bounded Contexts from the book “Implementing Domain-Driven Design” by Vaughn Vernon. GitHub.
[7] Vernon, V. (2013). Implementing Domain-Driven Design (1st ed.). Addison-Wesley Professional.
[8] Wikipedia contributors. (2021, November 22). Domain-driven design.