شما اینجا هستید: خانه / مقالات آموزشی / آشنایی با مفاهیم Domain-Driven Design – بخش اول

آشنایی با مفاهیم Domain-Driven Design – بخش اول

در پست قبلی با کلیات رویکرد Domain-Driven و همچنین مفهوم Domain Model اشنا شدیم. در این مقاله به بررسی برخی مفاهیم جهت پیاده سازی Domain Model در نرم افزار می پردازیم.

  • Entity

Entity (به فارسی : موجودیت) به اشیایی گفته می شود که با ID (شناسه ی منحصر به فرد) تعریف و شناخته می شوند. برای مثال “مشتری” در سیستم فروش یک Entity می باشد. Entity در قالب یک کلاس با مشخصه ها (Attributes) و رفتارهای مختلف (Behaviors) پیاده سازی می شود. ویژگی ها و صفات مشتری ممکن است در طول عمر نرم افزار تغییر کند و ویرایش شود، اما ID آن ثابت است. ID می تواند مقداری واقعی و معنی دار مانند شماره ی شناسنامه ی مشتری، و یا مقداری تخصیص شده توسط خود نرم افزار مانند کد اشتراک مشتری باشد.  دو Entity مختلف می توانند ویژگی های یکسان داشته باشند بنابراین هر Entity باید متدی برای متمایز کردن خود از سایرین داشته باشد.

نمونه ای ساده از اینترفیس IEntity و موجودیت Custmer :

 
همانطور که ملاحظه میکنید جهت متمایز کردن Entity ها از یکدیگر متدی با نام SameIdAs تعریف و پیاده سازی شده است.

نکته : در مثال فوق ویژگی های موجودیت مشتری Encapsulate شده و قابلیت تغییر آنها از بیرون از کلاس وجود ندارد. این تکنیک باعث می شد تا مقادیر Property ها تنها توسط خود Entity تغییر یابد و Entity همیشه در وضعیت معتبر باشد. (می توانید جهت تغییر Property ها متدی مانند Update بر روی کلاس مشتری تعریف نمایید.)

  • Value Object

Value Object ها اشیایی هستند که تنها توسط ویژگی ها و مقادیرشان شناخته می شوند و برای سیستم اهمیت دارند. برای مثال “آدرس مشتری” می تواند در قالب یک Value Object طراحی شود. Value Object ها می توانند به Entity های مختلف تخصیص داده شوند و معمولا به صورت Immutable پیاده سازی می شوند.

برای مثال در کد زیر کلاس Address در قالب یک Value Object طراحی شده و در کلاس مشتری استفاده شده است :

 

  • Service

برخی عملیات ها در سیستم مربوط به یک شیء خاص نبوده و نمیتوان آنها را در قالب یک شیء و یا رفتاری از یک شیء در نظر گرفت. این نوع عملیات ها در قالب یک Service نوشته شده و در قسمت های مختلف برنامه استفاده می شوند. Service ها به صورت Stateless طراحی می شوند، یعنی هیچگونه وضعیتی را در خود نگهداری نمی کنند. از آنجا که سرویس ها می توانند به ابزارهای زیر ساختی (مانند دیتابیس) و یا وب سرویس های Remote دسترسی داشته باشند، لذا Interface آنها در لایه ی Domain و پیاده سازی واقعی آنها در لایه های دیگر انجام میگیرد تا Domain به دیگر لایه ها وابسته نشود.

سرویس ها در DDD معمولا به ۳ دسته تقسیم می شوند :

Domain Service : سرویس هایی که مربوط به Business و لایه ی Domain نرم افزار می شوند. این سرویس ها معمولا پیاده سازی یک فرآیند، اعتبارسنجی یک فرآیند و یا بازیابی داده ها برای یک فرآیند (از طریق Repository ها) را برعهده دارند. Domain Service ها اغلب به داخل متدها و سازنده ی Entity ها Inject شده و استفاده می شوند.

Application Service : سرویس هایی که با کلاینت های بیرونی ارتباط دارند و پیام ها و دستورات (Commands) را به عملیات ها و پردازش های داخلی Domain تبدیل و اجرا میکنند.

Infrastructure Service : سرویس هایی که با منابع و وب سرویس هایی Remote در ارتباط هستند. ( مانند سرویسی که مسئول ارتباط با وب سرویس ارسال پیامک است)

در این مقاله با ۳ مفهوم Entity، Value Object و Service در DDD آشنا شدیم. در مقاله های بعد به بررسی مفاهیمی مانند Aggregate، AggregateRoot، Bounded Context و … می پردازیم.

درباره هادی احمدی

هادی احمدی
برنامه نویس، تحلیلگر و طراح نرم افزار که به فعالیت بر روی بسترهای نرم افزاری مایکروسافت مشغول هستم. علاقه مند به مباحث طراحی و معماری نرم افزار و همچنین پیاده سازی سیستم های اطلاعاتی پیچیده می باشم.

30 نظر

  1. امیرحسین جلوداری

    سلام …
    خیلی ممنون بابت مقاله ی خوبتون … امیدوارم که همینطوری ادامه بدین …

    میشه یه مرجع خوب و سریع و به روز برای یادگیری این موضوع (طراحی DDD) معرفی کنین؟

    • هادی احمدی

      سلام
      خواهش میکنم
      در هفته های آینده یک مطلب کامل در مورد منابع و همچنین سورس کدهای موجود در اینترنت جهت یادگیری DDD مینویسم.
      از نظر من کتاب خود آقای Eric Evans به نام Domain-Driven Design: Tackling Complexity in the Heart of Software و همچنین کتاب Implementing Domain-Driven Design نوشته آقای Vaughn Vernon بهترین منابع موجود هستند.

  2. سلام
    مرسی بابت مطابت خوبتون امیدوارم همچنان به اشتراک گذاری دانشتون ادامه بدید :)

  3. سلام
    درسته که منابعی که گفتین بهترین منابع هستند ولی مطلب فارسی کاملی نداریم. امیدوارم تمام دانشتون در این زمینه رو منتقل کنید.

    • هادی احمدی

      سلام
      درست میفرمایید، منبع فارسی در رابطه با DDD موجود نیست.
      من حتما سعی میکنم مبحث رو تا جای عملی و کاربردی پیش ببرم.

  4. آرمان عرفانی

    خیلی عالی، مشتاقانه منتظر باقی مطالب هستیم.

  5. سلام. ممنون میشم اگه مقایسه ای بین domain service و Application Service داشته باشید و وظایف هر کدام را شرح دهید اگر با یه قطعه کد توضیح بدید ممنون میشم.

    • هادی احمدی

      سلام
      Application Service در واقع حاوی Application Logic می باشد و مراحل مورد نیاز مختلف برای انجام یک Use Case را هماهنگ میکند و انجام می دهد. برای مثال در Use Case ثبت نام کاربر، ابتدا Entity را می سازد، سپس آن را به Repository مربوط جهت ذخیره سازی ارسال میکند و سپس سرویس ارسال ایمیل را فراخوانی می کند. ( در اصطلاح فنی، یک Use Case را Orchestrate میکند)

      در مقابل Domain Service حاوی Domain Logic می باشد و سرویس هایی در سطح Domain هستند که اغلب رفتارهایی مربوط به Business دارند. کاربردهای مختلفی برای Domain Service می توان نام برد.
      ۱٫ پیاده سازی یک منطق Reusable و قابل تغییر در سطح Domain. برای مثال سرویس محاسبه ی مالیات می تواند متغیر باشد، به همین دلیل در قالب Domain Service های مختلف نوشته می شود و به صورت Interface در اختیار کلاس های Domain قرار میگیرد.
      ۲٫ Abstract کردن لایه های زیرساختی از دید کلاس های Domain. برای مثال هنگامی که یک کلاس Domain (به هر دلیلی) به خواندن داده از دیتابیس نیاز دارد، Repository مستقیم به Entity داده نمی شود، بلکه این سرویس در قالب یک Domain Service در اختیار آن قرار میگیرد و Domain Service از Repository (و یا هرمکانیزم دیگری) برای خواندن اطلاعات استفاده میکند.
      ۳٫ در مواردی که یک فرآیند Domain در قالب یک Entity مدل نمی شود و نیاز است تا عملیات بین چند Entity به عنوان یک رفتار Business مدل شوند.

      برای نمونه کد و اطلاعات بیشتر به لینک زیر مراجعه نمایید :

      Services in Domain-Driven Design

  6. سلام مهندس
    آقا دمت گرم عالی بود.

  7. با سلام و عرض خسته نباشید و تشکر از مقاله خوبتون.
    اگه امکانش هست میشه یکم در مورد این متد SameIdAs که در کلاس Customer نوشتید توضیح بدید؟ ممنونم

    • هادی احمدی

      سلام، خواهش میکنم

      از آنجا که برابر بودن دو Entity از طریق Id انها چک می شود، برای صریح بودن این موضوع پیشنهاد می شود از متد جداگانه ای استفاده شود. این متد همچنین در Equals هم صدا زده می شود.

  8. سلام آقای احمدی
    سوآلی درمورد object value هایی که بهصورت id در aggrigate root موجود هستن داشتم

  9. عرض سلام
    داخل گوگل وقتی کلمه onion architecture سرچ میکنیم بعضی عکسها که فکر کنم اشتباه باشه کلاس ریپازیتوری در لایه Domain Service معرفی کردن و عکسهای بیشتری که فکر کنم درست باشه اینترفیس های ریپازیتوری در لایه Domain Service معرفی کردن
    نظرتون در این مورد بفرمایید تشکر

    • هادی احمدی

      سلام

      جناب قاسمی عزیز، تعریف Repository (منظور Interface آن) جزئی از Domain شما می باشد. پیشنهاد میکنم برای درک صحیح مفاهیم، کتاب های مرجع Domain-Driven Design را مطالعه بفرمایید. در همه ی کتاب ها مبحثی به نام Repository وجود دارد که به تعریف کامل این موضوع پرداخته شده است.

  10. بسیار عالی

    خوبه که مطالبی راجع به DDD در سطح فارسی نوشته میشه

  11. سلام
    استاد بسیار لذت بردم
    متشکرم

  12. سلام واقعا عالی بود
    دستتون درد نکنه

  13. امیر حسین امینی

    سلام استاد ببخشید یه سوال برای من بوجود اومد
    در یک پروژه که تعداد زیادی Api Service(Infrastructure Service ) وجود دارد
    چطور این سرویس ها رو باید پیاده سازی کنیم که بتونیم از این Infrastructure Service ها در لایه UI
    استفاده کنیم و دسترسی داشته باشیم
    ممنونم

  14. سلام وقتتون بخیر
    ببینید ساختار زیر در مورد پیاده سازی یه نرم افزار تیکتینگ درسته :

    Aggregate root ی بنام تیکت داریم . هر تیکت می تونه تعدادی گیرنده (Receivers) داشته باشه. گیرنده ها رو به عنوان Value object در نظر گرفته ایم. آیا این درسته ؟
    Value Object ی که به صورت یه لیست هست مانند مثال بالا که یه Collection از گیرنده ها برای هر تیکت وجود دارد. و از انجایی که Value Object ها Immutable هستند، در لایه دیتابیس برای مدیریت گیرنده ها باید فقط ثبت و حذف داشته باشیم یا اینکه می تونیم ویرایش هم انجام بدیم؟

    • هادی احمدی

      سلام یونس جان.
      نظر دادن در مورد Domain Model یک مساله و طراحی آن، نیاز به اطلاعات بیشتر از فضای دامنه، Invariant ها و همچنین نیاز مساله و Use Case های مورد نیاز دارد. بنابراین ممکن است راهنمایی من (به علت نداشتن اطلاعات در مورد مساله) درست نباشد. ولیکن یک لیست از Id مربوط به Aggregate گیرنده، می تواند به شکل Value Object بر روی تیکت مدل شود. پیشنهاد می شود از نگه داشتن مستقیم List Id خودداری کنید و یک Value Object جهت Encapsulation بهتر و همچنین مدل کردن بهتر رفتار آن، ایجاد کنید.

      پیشنهاد می شود با Value Object ها به صورت Immutable برخورد کنید.

دادن پاسخ بهامیر حسین امینی بی خیال پاسخ!

آدرس ایمیلتان منتشر نمیشودگزینه های الزامی ستاره دار شده اند *

*

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

رفتن به بالا