
آموزش طراحی دامنه محور در سی شارپ Domain Driven Design
آموزش طراحی دامنه محور در سی شارپ Domain Driven Design یکی دیگر از آموزش های گروه آموزشی پرووید می باشد که در این قسمت آن را به شما معرفی می کنیم. این بسته ی آموزشی نیز یکی از دوره های آموزشی دیگر که در حوزه ی فارسی سازی آموزش های انگلیسی تنظیم شده است می باشد. عنوان این بسته ی آموزشی طراحی دامنه محور و میکروسرویس ها در سی شارپ است که با نام اصلی آموزش طراحی دامنه محور در سی شارپ Domain Driven Design Fundamentals از شرکت Pluralsight منتشر شده است.
طراحی دامنه محور یا Domain-Driven Design چیست؟
طراحی دامنه محور برای توسعه نرم افزار و همچنین جلوگیری از پیچیدگی آن است. هدف اصلی Domain-Driven Design در توسعه نرم افزار این است که با اتصال به قسمت های مربوط به نرم افزار در حال توسعه، ساختن برنامه های پیچیده را آسان کند. به عبارت دیگر DDD بر سه اصل اصلی تمرکز می کند:
- بر core domain و domain logic تمرکز دارد.
- می توانید پایه و اساس طرحهای پیچیده را بر اساس مدلهای domain تنظیم کنید.
- به طور مداوم با متخصصان domain همکاری دارید تا مدل برنامه را بهبود بخشیده و هر گونه مسائل مرتبط با domain را حل کنید.
در طراحی دامنه محور، اریک ایونز چند اصطلاح رایج را که هنگام توصیف و بحث در مورد فاکتور ها و روش هایی که در DDD مفید هستند، اینگونه بیان می کند:
- Context: تنظیماتی که در آن یک کلمه یا یک عبارت نمایش داده می شود و معنای آن را تعیین می کند. در واقع جملات در مورد یک مدل فقط در یک Context قابل درک است.
- Model: سیستمی از abstraction ها که aspect های انتخاب شده یک domain را توصیف می کند و می تواند برای حل مشکلات مربوط به آن domain مورد استفاده قرار گیرد.
- Ubiquitous Language: زبان فراگیر یا Ubiquitous Language زبانی است که حول محور domain model سازماندهی می شود و توسط همه اعضای تیم به منظور ارتباط برقرار کردن فعالیت های تیم با نرم افزار در دست ساخت مورد استفاده قرار می گیرد.
- Bounded Context: توصیف یک مرز یا boundary (معمولاً یک زیر سیستم، یا کار یک تیم خاص) که در آن یک مدل خاص تعریف شده و قابل اجرا است.
بررسی Building Block ها
طراحی دامنه محوریا همان Domain-driven design تعدادی از مفاهیم سطح بالا را تعریف می کند که می توانند در کنار یکدیگر برای ایجاد و اصلاح domain model ها استفاده شوند:
- Entity: یک object می باشد که بر اساس تداوم پیوسته اش تعریف می شود، در مقایسه با object های سنتی که توسط attribute هایشان تعریف می شوند.
- Value Object: یک آبجکت immutable است یعنی غیرقابل تغییر است و که دارای ویژگی هایی است، اما identity منحصر بفردی ندارد.
- Domain Event: یک آبجکت است که برای ثبت یک رویداد مجزا مربوط به model activity در سیستم استفاده می شود. در حالی که همه event ها درون سیستم قابل ردیابی هستند، یک domain event فقط برای event type ها ایجاد می شود که متخصصان domain به آن اهمیت می دهند.
- Aggregate: یک کلاستر از entity ها و value object ها با مرزهای مشخص شده در اطراف گروه می باشد. به جای اینکه به هر entity یا value object اجازه دهید همه اقدامات را به تنهایی انجام دهد، این aggregate مجموعه ای از عناصر یک aggregate root منحصربه فرد را دریافت می کند. در حال حاضر، external object ها دیگر دسترسی مستقیم به هر موجودیت یا value object های درون Aggregate ندارند، بلکه فقط به یک root item واحد، دسترسی دارند و از آن برای ارسال دستورالعمل ها به کل گروه استفاده می کنند. این عمل با بسیاری از شیوه های برنامه نویسی واقعی که ما در سری آموزش الگو های طراحی (Design Pattern ها) در سی شارپ سایت توضیح داده ایم مرتبط است.
- Service: در اصل یک سرویس، عملیات یا شکلی از یک منطق تجاری است که به طور طبیعی در دنیای object ها قرار نمی گیرد. به عبارت دیگر، برخی از عملکردها باید وجود داشته باشند، اما نمی توانند به یک entity یا value object مربوط باشند.
- Repositories: این مفهوم با repository های version control اشتباه گرفته نشود، معنای DDD در واقع repository سرویسی است که از interface برای دسترسی به همه entity ها و value object ها در یک aggregate مجموعه خاص استفاده می کند. در واقع روش هایی باید تعریف شود که امکان ایجاد، اصلاح و حذف value object ها در همه جا را فراهم کند. با این حال با استفاده از این repository service برای ایجاد داده های پرس و جو و حذف چندین قابلیت پرس و جو، از داده ها از business logic مربوط به object model ها است.
- Factories: همانطور که قبلاً در تعدادی از مقاله های الگوهای طراحی بحث کردیم، DDD استفاده از factory را پیشنهاد می کند که منطق ایجاد object ها و ابزارهای پیچیده را در بر می گیرد و اطمینان حاصل می کند که مشتری از عملکرد داخلی object آگاهی ندارد.
Domain-Driven Design چیست و چه مشکلی را حل میکند؟
Domain-Driven Design یا DDD رویکردی برای طراحی نرمافزار است که بر شناخت دقیق حوزه کسبوکار و هماهنگکردن مدل نرمافزار با مفاهیم همان حوزه تمرکز دارد. در این رویکرد، توسعهدهندگان بهجای اینکه تنها بر ساختارهای فنی و Database تمرکز کنند، تلاش میکنند مسئله اصلی را درک کرده و مفاهیم آن را در طراحی سیستم منعکس کنند. این شیوه در پروژههایی که قوانین کسبوکار پیچیدهاند، میتواند به ایجاد ساختاری منسجمتر و قابلفهمتر کمک کند.

یکی از ویژگیهای مهم DDD، همکاری نزدیک میان افراد فنی و متخصصان حوزه کسبوکار است. استفاده از زبان مشترک برای توصیف مفاهیم و قوانین، احتمال برداشتهای متفاوت از نیازمندیها را کاهش میدهد. همچنین مدل دامنه باید بتواند تغییرات قوانین کسبوکار را بدون ایجاد پیچیدگی غیرضروری در تمام بخشهای برنامه مدیریت کند. درک این اصول به توسعهدهندگان C# کمک میکند هنگام طراحی نرمافزارهای پیچیده، تصمیمهای معماری را بر اساس ماهیت مسئله و نیازهای واقعی سیستم اتخاذ کنند.
مدلسازی دامنه و عناصر اصلی Domain Model
Domain Model نمایش مفاهیم، قوانین و رفتارهای مهم یک حوزه کسبوکار در نرمافزار است. این مدل صرفاً مجموعهای از کلاسهای داده نیست، بلکه باید قواعد و محدودیتهایی را نیز منعکس کند که رفتار سیستم را تعیین میکنند. هنگام طراحی مدل دامنه، توسعهدهنده باید مشخص کند چه مفاهیمی در حوزه موردنظر اهمیت دارند، چه ارتباطی میان آنها وجود دارد و هر مفهوم چه مسئولیتهایی بر عهده دارد. این فرایند به ساخت نرمافزاری کمک میکند که منطق اصلی آن با نیازهای کسبوکار هماهنگ باشد.
در DDD، مفاهیمی مانند Entity، Value Object و Domain Service نقشهای متفاوتی در مدلسازی دارند. Entity معمولاً با هویت مشخص خود شناخته میشود، در حالی که Value Object بر ویژگیهای مقدارمحور تکیه دارد و غالباً هویت مستقل ندارد. Domain Service نیز برای نمایش عملیاتی استفاده میشود که منطق دامنهای دارند، اما مسئولیت طبیعی آنها به یک Entity یا Value Object مشخص تعلق نمیگیرد. شناخت تفاوت این عناصر به توسعهدهندگان کمک میکند مدل دامنه را به شکلی روشنتر و متناسب با مسئولیتهای هر بخش طراحی کنند.
Aggregate و Repository در معماری DDD
Aggregate در Domain-Driven Design برای گروهبندی مجموعهای از اشیای دامنه و مشخصکردن مرزهای سازگاری آنها استفاده میشود. هر Aggregate یک نقطه ورود اصلی دارد که با عنوان Aggregate Root شناخته میشود و دسترسی به بخشهای داخلی باید از طریق قواعد تعریفشده مدیریت شود. این ساختار کمک میکند محدودیتهای مهم دامنه در یک محدوده مشخص حفظ شوند و تغییرات دادهها باعث نقض ناخواسته قوانین کسبوکار نشوند. طراحی صحیح Aggregateها در مدیریت پیچیدگی و تعیین مسئولیت اجزای مدل اهمیت دارد.

Repository نیز الگویی برای جداکردن منطق دامنه از جزئیات دسترسی به دادهها است. این الگو امکان میدهد کدهای دامنه برای بازیابی و ذخیره اشیای موردنیاز خود از یک رابط مشخص استفاده کنند، بدون اینکه مستقیماً به جزئیات زیرساخت ذخیرهسازی وابسته باشند. نحوه طراحی Repository باید با ساختار مدل دامنه هماهنگ باشد و نباید صرفاً به ایجاد یک لایه اضافی برای هر جدول Database محدود شود. آشنایی با ارتباط Aggregateها و Repositoryها به طراحی معماریهایی کمک میکند که منطق کسبوکار در آنها ساختارمندتر باقی میماند.
Domain Event و Anti-corruption Layer در طراحی نرمافزار
Domain Event رویدادی است که نشان میدهد اتفاق مهمی در حوزه کسبوکار رخ داده است؛ برای مثال، ممکن است وضعیت یک سفارش تغییر کند یا عملیاتی با اهمیت دامنهای به پایان برسد. ثبت و انتشار چنین رویدادهایی به بخشهای مختلف سیستم اجازه میدهد از تغییرات مهم مطلع شوند، بدون اینکه تمام اجزا مستقیماً به یکدیگر وابسته باشند. طراحی Domain Eventها باید با توجه به معنای واقعی رویداد و نیازهای سیستم انجام شود تا ارتباط میان اجزای دامنه روشن و قابلمدیریت باقی بماند.
Anti-corruption Layer نیز الگویی برای محافظت از مدل دامنه در برابر مفاهیم و ساختارهای نامتناسب سیستمهای دیگر است. زمانی که یک اپلیکیشن با سرویس خارجی یا سامانهای با مدل داده متفاوت ارتباط برقرار میکند، این لایه میتواند تفاوتهای ساختاری و معنایی را مدیریت کند و مانع از ورود مستقیم پیچیدگیهای بیرونی به مدل داخلی شود. در این آموزش، Domain Eventها و Anti-corruption Layer در کنار سایر مفاهیم DDD بررسی میشوند تا بتوانید روشهای مدیریت ارتباطات و تکامل مدل دامنه را بهتر درک کنید.
سرفصل مطالب آموزش ویدیویی طراحی دامنه محور در سی شارپ Domain Driven Design
فصل اول: مقدمه دوره آموزشی
- مقدمه دوره آموزشی
فصل دوم: مقدمه ای بر طراحی دامنه محور و یا Domain-Driven Design
- مقدمه
- در این دوره آموزشی چه چیزهایی را فرا خواهید گرفت؟
- بررسی کردن ارزش و اهمیت Domain-Driven Design
- کسب کردن یک درک سطح بالا از Domain-Driven Design
- بررسی کردن مزیت ها و معایب بالقوه Domain-Driven Design
- بررسی کردن یک Mind Map از Domain-Driven Design
- معرفی کردن اپلیکیشن مربوط به این دوره آموزشی
- بررسی کردن ساختار اپلیکیشن مورد نظر از سطح بالا
- جمع بندی
فصل سوم: مدل کردن مسئله و یا Problem ها در نرم افزار
- مقدمه
- معرفی کردن Domain
- برنامه ریزی کردن از قبل برای کشف کردن و یادگیری مسائل Domain
- صحبت کردن با Domain Expert ها و کشف کردن Domain و Subdomain ها
- صحبت کردن با Domain Expert ها و کشف کردن و زمانبندی کردن Subdomain ها
- بازبینی کردن مهمترین موضوعات حاصل شده از جلسات برگزار شده با Domain Expert ها
- انجام اولین تلاش در مدل کردن Subdomain
- استفاده کردن از Bounded Context ها برای کشف کردن مفاهیم و Concept هایی که مشترک هستند
- صحبت کردن با Eric Evans در مورد Subdomain ها و Bounded Context ها
- معرفی کردن Context Map ها
- حل کردن مسئله دیتابیس های تفکیک شده به ازای هر Bounded Context
- مشخص کردن Bounded Context ها در اپلیکیشن
- بررسی کردن Ubiquitous Language مربوط به Bounded Context
- صحبت کردن با یک Domain Expert و کار کردن بر روی Ubiquitous Language
- بازبینی کردن مفاهیم و Concept های مهم مربوط به این فصل
- جمع بندی
فصل چهارم: عناصر مربوط به Domain Model
- مقدمه
- اهمیت درک کردن واژگان مهم در Domain-Driven Design
- تمرکز کردن بر روی Domain
- مشخص کردن Event ها و Behavior ها
- مقایسه کردن Domain Model های Rich و Anemic
- درک کردن Entity ها
- تفاوت بین CRUD ها و مسائل پیچیده که از Domain-Driven Design استفاده می کنند
- جابجا شدن بین Context ها در UI
- استفاده کردن از GUID ها یا اعداد صحیح برای Identity Value ها
- صحبت کردن با Eric Evans در رابطه با مسئولیت Entity ها
- پیاده سازی کردن Entity ها در کد
- Synchronize کردن داده ها در Bounded Context های مختلف
- جمع بندی
فصل پنجم: درک کردن Value Object ها و سرویس ها در مدل
- مقدمه
- آشنا شدن با Value Object ها
- معرفی کردن Value Object های پرکاربرد
- کسب اطلاعات بیشتر از Eric Evans و Vaughn Vernon
- پیاده سازی کردن Value Object ها در کد
- درک کردن Domain Service ها
- جمع بندی
فصل ششم: حل و فصل کردن پیچیدگی با استفاده از Aggregate ها
- مقدمه
- حل و فصل کردن پیچیدگی داده ها
- معرفی کردن Aggregate ها و Aggregate Root ها
- کار کردن با Association ها در Aggregate ها
- کار کردن با Relationship هایی که بر روی چندین Aggregate وجود دارند
- تکامل پیدا کردن یک Aggregate
- استفاده کردن از Invariant ها برای بهتر فهمیدن Aggregate ها
- دستاورد های مدل سازی و Refactoring
- بررسی کردن علائم مربوط به عدم شناخت دقیق یک Aggregate
- ایجاد کرددن یک Aggregate جدید
- بررسی کردن Aggregate ایجاد شده
- بررسی نکات اساسی طراحی Aggregate ها
- جمع بندی
فصل هفتم: کار کردن با Repository ها
- مقدمه
- مقدمه ای بر Repository ها
- مزایای استفاده از Repository ها
- نکات مربوط به Repository ها
- عدم استفاده کردن از Repository Blunder ها
- صحبت کردن در رابطه با اختلاف نظر مربوط به استفاده کردن از Repository ها
- مزیت ها و معایب کار کردن با IQueryable
- کار کردن با Repository های جنریک و اینترفیس ها
- بررسی کردن Repository ها در اپلیکیشن
- معرفی کردن Specification Pattern
- استفاده کردن از Specification ها با Repository ها در اپلیکیشن
- جمع بندی
فصل هشتم: اضافه کردن Domain Event ها و بررسی Anti-corruption Layer
- مقدمه
- معرفی Domain Event ها
- مشخص کردن Domain Event ها در سیستم
- طراحی کردن Domain Event ها
- اعمال کردن Domain Event ها به یک اپلیکیشن ساده
- بررسی کردن Domain Event ها در اپلیکیشن
- معرفی کردن Anti-Corruption Layer ها
- جمع بندی
فصل نهم: تکامل اپلیکیشن با استفاده از Domain-Driven Design
- مقدمه
- بازبینی طراحی فعلی اپلیکیشن
- پیاده سازی یک قابلیت جدید با کمک یک Domain Expert
- برنامه ریزی کردن مراحل مربوط به پیاده سازی
- معرفی کردن Message Queue ها
- ارسال کردن یک Message بر روی Queue
- خواندن یک Message از روی Queue و پردازش کردن آن
- استفاده کردن از چندین Queue برای Handle کردن چندین ارتباط
- رفع خطا و یا Debug کردن به منظور دیدن جزئیات مربوط به کد
- اهمیت Microservice ها
- به اشتراک گذاشتن نکات مربوط به گسترش دادن و اجرا کردن برنامه
- بررسی کردن واسط برنامه و یا UI در Domain Design
- بررسی در طراحی Domain
- مدل سازی با Event Storming و تکنیک های دیگر
- صحبت های Eric Evans در رابطه با دلیل اهمیت ایده آل گرا نبودن
- جمع بندی و معرفی منابع







