فرشید عزیزی
فرشید عزیزی
خواندن ۸ دقیقه·۳ سال پیش

آموزش کاربردی DDD in ASP.NET Core - قسمت اول

 DDD in ASP.NET Core applications
DDD in ASP.NET Core applications


تاکنون معماری های زیادی برای کاهش هزینه های نرم افزار برای مشتریان و افزایش طول عمر نرم افزار ابداع شده است. از multi-layered تا multi-tiered و به دنبال آن یک معماری دامنه گرا(Domain Oriented Architecture).

الگوی های معماری Multi-layer و Multi-tier

معماری Multi-layer

در شکل زیر نمونه ای از لایه های یک web application را مشاهده می کنید:

Multi-layer architecture
Multi-layer architecture

برای هدف بحث، بیایید فرض کنیم که یک اپلیکیشن ساختگی Educator Tools داریم که برای کمک به اوایای مدرسه در مدیریت دانش‌آموزان دبیرستانی طراحی شده است.

  • لایه Presentation نمایانگر رابط گرافیکی کاربر برای تعامل کاربر با برنامه است. به عنوان مثال، در برنامه Educator Tools، ممکن است دکمه ای داشته باشیم که با کلیک کردن، با لایه Controller ارتباط برقرار می کند تا پروفایل یک دانش آموز را بازیابی و به کاربر مربوطه نمایش دهد.
  • لایه Controller درخواست هایی که از سمت لایه Presentation به سرور می آیند را پردازش می کنند. کنترلرها عملیاتی را برروی Model داده ها انجام می دهند و View مناسب برای ارسال به کلاینت را انتخاب می کنند.آنها گلوگاه ارتباطی بین درخواست ها و پاسخ ها هستند و نقش اصلی آنها کنترل جریان و فرآیند کار است. اما کار واقعی در لایه‌های زیر Controller اتفاق می‌افتد.
  • لایه business logic منطق کسب و کار و قوانین آن را تعریف و اجرا می کند. به عنوان مثال، برنامه Educator Tools دارای ویژگی ای است که می تواند به کاربر اطلاع دهد که آیا یک دانش آموز می تواند فارغ التحصیل شود یا خیر. دانش آموز می تواند فارغ التحصیل شود، مشروط بر اینکه تمام دروس را گذرانده باشد، در امتحانات نهایی شرکت کرده باشد و البته شهریه مدرسه را نیز پرداخت کرده باشد. قوانین برای تعیین اینکه آیا دانشجو می تواند فارغ التحصیل شود یا خیر، ممکن است در کلاسی در لایه service تعبیه شود. این کار به جبه تفکیک نگرانی ها کمک می کند، لایه service اغلب وظایف بازیابی داده‌ها از داده های ذخیره‌سازی‌ شده را به لایه persistence محول می‌کند.
تفکیک نگرانی(Separation of Concerns یا به اختصار SoC هم گفته می شود) چیست؟ در علوم کامپیوتری، جداسازی نگرانی‌ها (SoC) یک اصل طراحی برای جدا کردن یک برنامه کامپیوتری به بخش‌های مجزا است، به طوری که هر بخش به یک نگرانی جداگانه می‌پردازد. ما از این اصل برای جداسازی ماژول های برنامه برای مدیریت برنامه های کاربردی مقیاس پذیر(scalable applications) استفاده می کنیم.
  • لایه Data persistence شامل منطق بازیابی و ذخیره داده ها به انبارهایی مانند پایگاه داده، فایل ها،ذخیره سازی در فضای ابری و ... همچنین نگاشت داده ها به اشیاء دامنه است(mapping the data into domain objects).
تصویر بالا فقط نمونه ای از لایه ها در یک برنامه کاربردی است. در عمل، یک برنامه سازمانی ممکن است دارای لایه های بیشتر یا کمتری باشد. به عنوان مثال، در برنامه های کاربردی ساده ممکن است business logic و Data persistence در یک لایه باشد. از سوی دیگر، برنامه‌های پیچیده ممکن است لایه‌های Data persistence جداگانه برای انواع مختلف داده یا ذخیره‌سازی داشته باشند.

معماری لایه باز در مقابل بسته(Closed vs open layer architecture)

  • در تصویر بالا، فلش ها رو به پایین هستند تا نشان دهند که یک لایه فقط به لایه دیگری که بلافاصله زیر آن است بستگی دارد. این نوع معماری لایه ای(layered architecture)، به معماری لایه بسته(closed layer architecture) معروف است. اگر به درستی انجام شود، معماری لایه بسته کوپلینگ ها(couplings) را در یک برنامه کاهش می دهد. برای مثال، فرض کنید در اپلیکیشن Educator Tools، می خواهیم ORM framework را از Entity Framework به Dapper تغییر دهیم. در معماری لایه بسته، ما فقط نیاز به بروز رسانی لایه service داریم. ما نباید لایه Controller یا لایه Presentation را به روز کنیم زیرا آنها به لایه Data persistence بستگی ندارند.
  • گاهی اوقات لازم است که یک لایه کلاس ها را در لایه دیگری که بلافاصله زیر آن قرار ندارد فراخوانی کنید. به عنوان مثال، در برنامه Educator Tools، در زیر لایه persistence، می‌توانیم یک لایه مشترک داشته باشیم که حاوی توابع کمکی، کلاس‌های استاتیک، ثابت‌ها و غیره برای به اشتراک گذاشتن در سراسر برنامه است. هر دو لایه service و لایه Controller ممکن است نیاز به دسترسی به کلاس ها در لایه مشترک بدون عبور از لایه persistence داشته باشند. این نوع معماری به معماری لایه باز معروف است.
تعريف Coupling : یک مقیاس اندازه گیری است برای اینکه بفهمیم دو کلاس/ماژول چقدر با هم در ارتباط هستند و چقدر روی هم تاثیر می گذارند .بهتر است که کلاسها/ماژول ها با هم ارتباط کمتری داشته باشند و در اصل ما دوست داریم که در مدلمان Coupling کم(Low Coupling) باشد.

معماری Multi-tier

  • همانطور که معماری Multi-layer یک برنامه کاربردی را به لایه های منطقی جدا می کند، معماری Multi-tier نیز یک برنامه را به لایه های فیزیکی جدا می کند. به عنوان مثال، در برنامه Educator Tools، لایه persistence ممکن است در سروری قرار گیرد که جدا از محل قرارگیری لایه‌های business logic و Controller است، و لایه Presentation در یک لایه جداگانه مانند Single Page Application (SPA) ها قرار دارد. یک برنامه پیچیده تر می تواند سطوح بیشتری داشته باشد.


معماری دامنه گرا(Domain Oriented Architecture)

خوب حالا می خواهم به مفهومی اشاره کنم که جدید نیست، اما این روزها رویکردی موثر برای ساخت اکثر برنامه های کاربردی وب محسوب می شود. این طراحی دامنه محور/Domain Driven Design (با نام مستعار DDD) است. ترکیب، بهبود و توسعه فوق العاده آن بر کاستی های مدل های قدیمی محبوب مانند N-Tiers، MVC، MVP، MVVM غلبه می کند.

در این پست و پست های بعدی، برخی از مفاهیم اساسی الگوی DDD را بررسی خواهم کرد و یک مثال عملی از نحوه اعمال موثر DDD در یک پروژه معمولی NET Core. ارائه خواهم کرد.


طراحی دامنه محور چیست و چرا به آن نیاز داریم؟

در سال 2003، اریک ایوان(Eric Evans) اولین کتاب را با عنوان "مقابله با پیچیدگی در قلب نرم افزار/Tackling Complexity in the Heart of Software" منتشر کرد که اولین مفاهیم را به DDD آورد. محبوبیت این الگو از آن زمان به طور تصاعدی افزایش یافته است. بسیاری از تیم‌ها، کسب‌وکارها یا شرکت های توسعه نرم‌افزار از این مدل استفاده کرده‌اند و به موفقیت‌های بزرگی در توسعه نرم‌افزار دست یافته‌اند. بیایید تعدادی از بهترین تعاریف DDD را باهم ببینیم :

«طراحی دامنه محور DDD از مدل‌سازی مبتنی بر واقعیت کسب‌وکار مرتبط با عنوان use case های شما حمایت می‌کند. در زمینه ساخت برنامه های کاربردی، DDD در مورد مشکلات به عنوان دامنه/Domain صحبت می کند. حوزه‌های مشکل‌ساز مستقل را به‌عنوان Bounded Contexts توصیف می‌کند (هر Bounded Contexts با یک میکروسرویس می تواند مرتبط باشد) و بر زبان مشترک (Ubiquitous Language) برای صحبت در مورد این مشکلات تأکید می‌کند. همچنین مفاهیم و الگوهای فنی زیادی را پیشنهاد می‌کند، مانند domain entities با rich models و value objects و aggregates و aggregate root(بعدا بصورت مفصل راجع به آنها صحبت خواهیم کرد)

طراحی دامنه محور DDD یک رویکرد برای توسعه نرم افزار متمرکز بر کسب و کار(business) است. مشکلات و چالش هایی که در طول توسعه و نگهداری نرم افزار رخ می دهد، بیشتر از رشد مداوم کسب و کار ناشی می شود. بنابراین، DDD به ارتباط نزدیک توسعه نرم افزار و تکامل مدل کسب و کار کمک می کند.

طراحی دامنه محور DDD به حل مشکل ساخت سیستم های پیچیده کمک می کند. این الگو به معماران، توسعه دهندگان و کارشناسانی در این حوزه نیاز دارد تا ابتدا الزامات را دقیقاً درک کنند. سپس رفتارها را تعریف می کنند، قوانین را درک می کنند، اصول و منطق کسب و کار را در مجموعه بندها (Abstractions، Interfaces و غیره) اعمال می کنند. در مرحله بعد، توسعه دهندگان آنها را در لایه های دیگر (به عنوان مثال، Application Layer و Infrastructure layer) پیاده سازی خواهند کرد. امروزه، DDD به عنوان یک استاندارد برای توسعه معماری های محبوب مختلف، مانند Onion Architecture، Clean Architecture، Hexagonal Architecture و غیره تنظیم شده است.

قبل از پرداختن به جزئیات، برخی از مزایا و معایب طراحی Domain-Driven را توضیح خواهم داد تا به شما در درک اینکه آیا این مدل به خوبی با پروژه شما مطابقت دارد یا خیر، کمک کند.


مزایا و معایب طراحی دامنه محور DDD

مزایای DDD :

اول Loose coupling : بخش‌های سیستم از طریق تعاریف و اصولی که در لایه Core (از جمله interfaces, abstract classes, base classes و غیره) گذاشته شده‌اند، با یکدیگر تعامل خواهند داشت. پیاده سازی در لایه های باقی مانده تکمیل خواهد شد. پیاده سازی ها از طریق کتابخانه های DI (IoC، AutoFac,...) خواهد بود.

دوم Flexibility یا انعطاف‌پذیری: تعاریف سطح بالا به تیم اجازه می‌دهد تا بدون تأثیر قابل‌توجه بر سیستم کلی، انعطاف‌پذیری بیشتری با الزامات عملکردی جدید افزایش دهد و با آنها سازگار شود.

سوم Testability تست پذیری: همانطور که در بالا ذکر شد، جداسازی پیاده سازی از رابط های(interfaces) تعریف شده در لایه Core، آزمایش با داده های ساختگی یا همان قابلیت تست پذیری را بهبود می بخشد.

چهارم Maintenance نگهداری: DDD به وضوح کلاس ها را بین layers/tiers تقسیم می کند. به طور خاص، Domain منطق تجاری(business logic) را پیاده‌سازی می‌کند، Infrastructure مسئول data persistence است، و Application مدیریت API و منطق یکپارچه‌سازی را بر عهده دارد. پیروی از این رویکرد در نهایت به شما شانس نوشتن کدهای تمیزتر و قابل اعتمادتر را می دهد. به علاوه، تیم شما می تواند به راحتی کد را پیدا کند، تکرار آن را محدود کند و زمان نگهداری را کاهش دهد.


معایب DDD

اول Domain expertise متخصص دامنه: DDD به متخصص دامنه نیاز دارد. این بدان معناست که تیم شما باید حداقل یک متخصص دامنه داشته باشد. آنها به شما کمک می کنند تا تمام فرآیندها، رویه ها و اصطلاحات آن دامنه را تعریف کنید.

دوم Low interactions تعاملات کم: loose connection بین بخش‌های مختلف مستلزم برقراری ارتباط و تبادل منظم تیم است. بنابراین قبل از اعمال رویکرد DDD، تیم باید ابتدا اصول آن را به تفصیل مورد بحث قرار دهد.

سوم Development costs هزینه های توسعه: کارشناسان دامنه و تیم باید مقدار زیادی کپسوله سازی(encapsulation) را در Domain Model پیاده سازی کنند. این اغلب منجر به توسعه و مدت زمان طولانی تر می شود که می تواند هزینه نسبتاً بالایی داشته باشد. بنابراین، برای پروژه های کوتاه مدت یا پروژه های بدون پیچیدگی دامنه زیاد مناسب نیست.


لایه ها در DDD

معماری پروژه های DDD معمولاً شامل سه بخش اصلی است: Domain, Infrastructure, Application. بسته به اندازه هر پروژه می توانیم این قسمت ها را در یک پروژه مرتب کنیم و یا در لایه های مختلف جدا کنیم.

Layers in DDD
Layers in DDD


بخش Domain: (بیشتر بخوانید : لایه ها در DDD - دامنه (Domain))

  • Entities
  • Aggregate
  • Value objects
  • Interfaces
  • Repository Interfaces/ServiceBase
  • ILogger/DTOs/Exceptions
  • Others

بخش Application :

  • Mobile application
  • Web MVC/API application
  • Desktop application
  • IoT
  • Others services

بخش Infrastructure :

  • Repositories
  • Data access(EntityFramework, Dapper, and ORM, etc.)
    In-Memory stores.
    Caching, NoSQL, and so on.
    Data seeding
  • Others:Logging.
    Cryptography.
    Etc.


آموزش کاربردی DDD in ASP.NET Core - قسمت دوم

بیشتر بخوانید : نقشه راه توسعه دهندگان Asp.NET Core


https://zarinp.al/farshidazizi

dddASPNET COREطراحی دامنه محور
Software Engineer
شاید از این پست‌ها خوشتان بیاید