عنوان:

‫Domain-Driven Design (DDD)؛ بخش سوم: تکنیک‌های کشف و درک دقیق دامنه کسب‌وکار


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۵/۲۹ ۰۸:۱۰
آدرس: www.dntips.ir
کشف دامنه: اولین قدم در معماری نرم‌افزارهای قدرتمند

تا به حال شده که یک پروژه را با فرض اینکه همه چیز را می‌دانید، شروع کنید و در میانه راه متوجه شوید که چیزهای زیادی را نادیده گرفته‌اید؟ در دنیای توسعه نرم‌افزار، این اتفاق به دفعات می‌افتد. ما اغلب عجله داریم که مستقیم به سراغ کدنویسی برویم، در حالی که مهم‌ترین مرحله را فراموش می‌کنیم: درک عمیق از مسئله‌ای که قرار است حل کنیم.
اینجاست که Domain Discovery یا "کشف دامنه" وارد میدان می‌شود، اولین و مهم‌ترین گام در طراحی استراتژیک Domain-Driven Design (DDD).

چرا کشف دامنه اینقدر حیاتی است؟

تصور کنید که در حال ساخت یک سیستم مدیریت کتابخانه هستید. ممکن است فکر کنید که دامنه شامل "کتاب‌ها"، "اعضا" و "امانت" است. اما آیا این تمام ماجراست؟
چه اتفاقی می‌افتد اگر یک کتاب دیر بازگردانده شود؟ قوانین جریمه‌ها چگونه است؟ آیا کتاب‌های مرجع (Reference Books) قوانین خاصی دارند؟ این جزئیات مهم، اغلب در ابتدای کار نادیده گرفته می‌شوند، اما پیچیدگی اصلی کسب‌وکار در همین جزئیات نهفته است.
کشف دامنه، فرآیند گفتگو، تحقیق و تحلیل برای درک کامل و دقیق دنیای واقعی کسب‌وکار است. این فرآیند ما را مجبور می‌کند که به جای حدس و گمان، به سراغ متخصصان و کاربران واقعی برویم و از آن‌ها یاد بگیریم.

تکنیک‌های کشف و درک عمیق

این فرآیند، تنها به چند جلسه پرسش و پاسخ ساده محدود نمی‌شود. ابزارها و تکنیک‌های قدرتمندی برای این کار وجود دارند:
  • مصاحبه با متخصصان (Domain Experts): متخصصان کسب‌وکار، گنجینه‌های اطلاعاتی هستند. آن‌ها دنیای واقعی را می‌فهمند و می‌توانند به شما بگویند که "قوانین بازی" چیست.
  • مشاهده و مشارکت: با کاربران نهایی صحبت کنید. ببینید چگونه کارها را انجام می‌دهند. در فرآیندهای آن‌ها مشارکت کنید تا پیچیدگی‌ها و چالش‌های واقعی را از نزدیک لمس کنید.
  • نمودار جریان کار (Workflow Diagrams): با رسم نمودارها، فرآیندها را از ابتدا تا انتها تجسم کنید. این کار به شما کمک می‌کند تا مراحل، تصمیم‌گیری‌ها و شرایط خاص را شناسایی کنید.
  • Event Storming: این یک کارگاه تعاملی و پرانرژی است که در آن، تمام اعضای تیم (فنی و کسب‌وکار) دور هم جمع می‌شوند و با استفاده از یادداشت‌های چسبان (sticky notes) رویدادهای مهم (مثلاً "کتاب امانت گرفته شد") و فرآیندهای کسب‌وکار را ترسیم می‌کنند.
کشف دامنه به ما اجازه می‌دهد تا از یک دید سطحی به یک دید عمیق و سه‌بعدی از کسب‌وکار برسیم. این مرحله، سنگ بنای تمام مراحل بعدی در DDD است. اگر این مرحله به درستی انجام نشود، تمام تلاش‌های بعدی برای طراحی نرم‌افزار، بر روی یک پایه سست بنا خواهد شد.
به این فکر کنید:
  • آخرین باری که یک پروژه را شروع کردید، چقدر زمان را به درک کامل مسئله اختصاص دادید؟
  • چه چیزی را ممکن است نادیده گرفته باشید که بعدها به یک مشکل بزرگ تبدیل شده است؟
با آغوش باز به استقبال پیچیدگی‌های دامنه بروید و آن‌ها را به چالش بکشید. در همین فرآیند کشف، خواهید دید که راه‌حل‌های هوشمندانه خودبه‌خود نمایان می‌شوند.


Event Storming: طوفان فکری برای نقشه‌برداری از دنیای واقعی 🤯

تا به حال در پروژه‌ای بوده‌اید که در آن، هر یک از اعضای تیم دیدگاه متفاوتی نسبت به فرآیندهای کسب‌وکار داشته باشند؟ متخصصان کسب‌وکار، توسعه‌دهندگان و حتی مدیران، هر یک از دریچه خود به مسئله نگاه می‌کنند. این عدم تفاهم، یکی از بزرگ‌ترین موانع در ساخت نرم‌افزارهای پیچیده است.
در Domain-Driven Design (DDD)، ما به دنبال ابزارهایی هستیم که این شکاف را پر کند و به یک درک مشترک از دامنه برسیم. Event Storming یکی از قدرتمندترین و جذاب‌ترین این ابزارهاست.

Event Storming چیست؟

Event Storming، در نگاه اول، یک کارگاه ساده و پرانرژی است. تمام اعضای تیم، از متخصصان دامنه گرفته تا توسعه‌دهندگان، در یک اتاق بزرگ دور هم جمع می‌شوند. ابزار اصلی ما؟ ماژیک و تعداد زیادی یادداشت چسبان (Sticky Notes) در رنگ‌های مختلف.
هدف اصلی، شناسایی و ترسیم تمام رویدادهای دامنه (Domain Events) است که در یک سیستم اتفاق می‌افتند. رویدادهای دامنه، به اتفاقات مهمی اشاره دارند که در گذشته رخ داده‌اند و برای کسب‌وکار ارزشمند هستند.
  • رویدادها به رنگ نارنجی: هر رویداد با یک یادداشت نارنجی رنگ نوشته می‌شود. مثلاً "کتاب امانت گرفته شد" یا "سفارش پرداخت شد".
  • ترسیم خط زمان: این یادداشت‌ها به صورت زمانی روی دیوار چیده می‌شوند، از گذشته به آینده. این کار به ما کمک می‌کند تا کل فرآیند را به صورت یک داستان بصری دنبال کنیم.
  • کشف جزئیات: همانطور که رویدادها را روی دیوار می‌چسبانید، سوالاتی مطرح می‌شود: "چه چیزی باعث این رویداد شد؟"، "چه کسی این کار را انجام داد؟" یا "چه اطلاعاتی برای این رویداد لازم است؟"
اینجاست که جادوی Event Storming اتفاق می‌افتد. با همکاری همه، سایر عناصر دامنه نیز به تدریج کشف و با رنگ‌های دیگر مشخص می‌شوند:
  • فرمان‌ها (Commands) به رنگ آبی: عمل‌هایی که باعث وقوع یک رویداد می‌شوند. مثلاً "ثبت سفارش".
  • موجودیت‌ها (Aggregates) به رنگ زرد: مدل‌هایی که مسئول اجرای یک فرمان و تولید یک رویداد هستند.
  • افراد یا سیستم‌ها (Actors) به رنگ صورتی: کسانی که فرآیند را آغاز می‌کنند.

چرا Event Storming اینقدر مؤثر است؟

  • هم‌ترازی تیم‌ها: وقتی همه در یک اتاق و رو به روی یک دیوار مشترک هستند، دیدگاه‌های متفاوت به یک درک واحد تبدیل می‌شود. توسعه‌دهنده متوجه پیچیدگی‌های کسب‌وکار می‌شود و متخصصان کسب‌وکار، محدودیت‌های فنی را درک می‌کنند.
  • کشف ابهامات و نقاط کور: با دیدن کل فرآیند به صورت بصری، ابهاماتی که در گفتگوهای ساده پنهان می‌مانند، آشکار می‌شوند.
  • برقراری زبان مشترک: Event Storming بهترین روش برای ایجاد و تثبیت Ubiquitous Language (زبان مشترک) است. واژه‌هایی که روی دیوار نوشته می‌شوند، به صورت مستقیم وارد کد و مکالمات روزمره تیم خواهند شد.
به این فکر کنید: آیا تا به حال در پروژه‌ای بوده‌اید که در آن، یک عبارت، معانی مختلفی برای افراد مختلف داشته باشد؟ اینجاست که Event Storming به عنوان یک ستون فقرات برای جلوگیری از چنین مشکلاتی عمل می‌کند.
Event Storming نه تنها یک تکنیک، بلکه یک تجربه مشترک و یک گفتگوی پربار است که به ما کمک می‌کند تا از یک دیدگاه تکی و جزیره‌ای، به یک دیدگاه جامع و یکپارچه از دامنه برسیم. این فرآیند، اولین گام عملی برای تبدیل پیچیدگی کسب‌وکار به یک مدل نرم‌افزاری واضح و قدرتمند است.

نظرات

  • وحید نصیری در ۱۴۰۴/۰۵/۲۹ ۰۸:۴۳
    مثالی از کشف دامنه و طوفان فکری: نقشه‌برداری از دنیای کتابخانه 📚

    تصور کنید که می‌خواهیم یک سیستم برای مدیریت یک کتابخانه بسازیم. اگر با روش سنتی به سراغ این پروژه برویم، شاید اولین کاری که می‌کنیم، ساختن جداولی مثل Books و Members در دیتابیس باشد. اما با این رویکرد، بسیاری از فرآیندهای پیچیده و حیاتی را نادیده می‌گیریم.
    در دنیای Domain-Driven Design (DDD)، اولین قدم ما، نشستن با متخصصان کتابخانه و کشف دقیق دنیای واقعی آن‌هاست. اینجاست که Event Storming به عنوان یک ابزار قدرتمند وارد عمل می‌شود.

    مرحله ۱: کشف دامنه با طوفان فکری

    برای شروع، یک کارگاه Event Storming با حضور تمام اعضای تیم (کتابداران، مدیران و توسعه‌دهندگان) برگزار می‌کنیم. ابزار ما ساده است: یک دیوار بزرگ و تعداد زیادی یادداشت چسبان (Sticky Notes) در رنگ‌های مختلف.

    گام اول: شناسایی رویدادها (Domain Events)
    از همه می‌خواهیم که تمام رویدادهای مهمی را که در کتابخانه اتفاق می‌افتند، روی یادداشت‌های نارنجی بنویسند. رویدادها باید در زمان گذشته بیان شوند، مانند:
    • کتاب امانت گرفته شد
    • عضویت جدید تمدید شد
    • کتاب به امانت گرفته‌شده دیر بازگردانده شد
    • جریمه پرداخت شد
    • کتاب به امانت گرفته‌شده مفقود شد
    این یادداشت‌ها را به ترتیب زمانی روی دیوار می‌چسبانیم. این کار یک دید کلی از فرآیندهای اصلی کتابخانه به ما می‌دهد.

    گام دوم: شناسایی فرمان‌ها (Commands)
    حالا برای هر رویداد، از خود می‌پرسیم که "چه چیزی باعث این رویداد شد؟" پاسخ‌ها را روی یادداشت‌های آبی می‌نویسیم.
    • رویداد:کتاب امانت گرفته شد
    • فرمان:ثبت امانت کتاب

    گام سوم: شناسایی موجودیت‌ها و Aggregates
    در این مرحله، از خود می‌پرسیم که "چه کسی یا چه چیزی مسئول اجرای فرمان‌هاست؟" پاسخ‌ها را روی یادداشت‌های زرد می‌نویسیم. این‌ها همان Aggregates یا ریشه‌های تجمیع ما هستند.
    • فرمان:ثبت امانت کتاب
    • مسئول:Book (کتاب) و Member (عضو)

    با ادامه این فرآیند، سایر جزئیات نیز کشف می‌شوند:
    • نقش‌ها (Actors) به رنگ صورتی: مانند کتابدار و عضو.
    • قوانین (Policies) به رنگ بنفش: مانند قانون محاسبه جریمه دیرکرد.

    مرحله ۲: ترسیم مدل و زبان مشترک

    پس از اتمام کارگاه، دیوار ما پر از اطلاعات ارزشمند است. ما اکنون یک نقشه بصری از دامنه کتابخانه داریم. این نقشه به ما کمک می‌کند که:
    • زبان مشترک (Ubiquitous Language) را تثبیت کنیم. کلماتی که روی دیوار می‌بینیم (مثل جریمه دیرکرد یا عضویت)، دقیقاً همان کلماتی هستند که باید در کد خود استفاده کنیم.
    • مرزهای Bounded Context را شناسایی کنیم. شاید Book Management و Member Management دو بخش اصلی باشند، اما Fines & Penalties (جریمه‌ها) می‌تواند یک زیردامنه مستقل با قوانین و Aggregate های خاص خود باشد.
    • مدل دامنه غنی را طراحی کنیم. اکنون می‌دانیم که کلاس Book فقط یک نگهدارنده اطلاعات نیست، بلکه دارای رفتارهایی مانند IsOverdue() یا CalculateFine() است.
    با استفاده از این دو تکنیک، ما از یک دیدگاه ساده و سطحی از "کتاب و عضو"، به یک درک عمیق از فرآیندهای پیچیده یک کتابخانه می‌رسیم. این فرآیند، سنگ بنای یک طراحی نرم‌افزاری موفق و پایدار است.
  • وحید نصیری در ۱۴۰۴/۰۵/۲۹ ۱۰:۲۹
    مثالی از کشف دامنه و طوفان فکری: مثال سیستم رزرو وقت ویزیت در مطب پزشک

    کشف دامنه (Domain Discovery) و طوفان فکری (Event Storming) ابزارهای کلیدی در معماری نرم‌افزارهای قدرتمند هستند که به ما کمک می‌کنند تا پیچیدگی‌های کسب‌وکار را درک کرده و مدل‌های نرم‌افزاری مؤثری طراحی کنیم. در این بخش، با استفاده از مثال سیستم رزرو وقت ویزیت در مطب پزشک، مراحل کشف دامنه و طوفان فکری را توضیح می‌دهیم.

    مرحله ۱: کشف دامنه با طوفان فکری
    هدف: درک فرآیندهای کسب‌وکار و شناسایی رویدادهای کلیدی در سیستم رزرو وقت ویزیت.
    طوفان فکری (Event Storming): در این روش، تیمی متشکل از توسعه‌دهندگان، متخصصان حوزه (مانند مدیر مطب یا پزشک) و سایر ذی‌نفعان گرد هم می‌آیند تا با طوفان فکری، رویدادهای مهم سیستم را شناسایی کنند. مراحل به‌صورت زیر است:

    گام اول: شناسایی رویدادها (Domain Events)
    رویدادها اتفاقاتی هستند که در دنیای واقعی رخ می‌دهند و برای کسب‌وکار اهمیت دارند. در سیستم رزرو وقت ویزیت، تیم با استفاده از یادداشت‌های رنگی (مانند استیکی‌نوت‌های نارنجی) رویدادها را روی یک تابلوی بزرگ می‌نویسد. مثال:
    • وقت ویزیت رزرو شد: بیمار یک وقت ویزیت برای روز و ساعت مشخص رزرو می‌کند.
    • وقت ویزیت لغو شد: بیمار رزرو خود را کنسل می‌کند.
    • ویزیت انجام شد: پزشک بیمار را معاینه کرد.
    • پرداخت انجام شد: بیمار هزینه ویزیت را پرداخت کرد.
    • یادآوری وقت ارسال شد: سیستم به بیمار یادآوری می‌کند که وقت ویزیت نزدیک است.

    گام دوم: شناسایی فرمان‌ها (Commands)
    فرمان‌ها اقداماتی هستند که باعث رخ‌دادن رویدادها می‌شوند. برای هر رویداد، تیم بررسی می‌کند چه عملی منجر به آن شده است. مثال:
    • فرمان: رزرو وقت ویزیت → منجر به رویداد “وقت ویزیت رزرو شد”.
    • فرمان: لغو رزرو → منجر به رویداد “وقت ویزیت لغو شد”.
    • فرمان: ارسال یادآوری → منجر به رویداد “یادآوری وقت ارسال شد”.

    گام سوم: شناسایی موجودیت‌ها و Aggregates
    موجودیت‌ها (Entities) اشیایی هستند که هویت مشخصی دارند و در سیستم نقش کلیدی ایفا می‌کنند. Aggregates گروهی از موجودیت‌ها هستند که به‌صورت یک واحد منسجم مدیریت می‌شوند. در سیستم رزرو وقت ویزیت:
    • موجودیت‌ها: بیمار، پزشک، وقت ویزیت، پرداخت.
    • Aggregates:
    • وقت ویزیت (Appointment): شامل اطلاعاتی مانند زمان، بیمار، پزشک و وضعیت (رزرو شده، لغو شده، انجام شده).
    • پرداخت (Payment): شامل مبلغ، روش پرداخت و وضعیت پرداخت.

    مرحله ۲: ترسیم مدل و زبان مشترک
    پس از شناسایی رویدادها، فرمان‌ها و موجودیت‌ها، تیم یک مدل دامنه ترسیم می‌کند و زبان مشترکی (Ubiquitous Language) ایجاد می‌کند که همه ذی‌نفعان (توسعه‌دهندگان، پزشکان، مدیران) از آن استفاده کنند. این زبان مشترک از سوءتفاهم جلوگیری می‌کند. مثال:
    • مدل دامنه: یک نمودار که نشان می‌دهد بیمار از طریق سیستم یک وقت ویزیت رزرو می‌کند، پزشک وقت را تأیید می‌کند، پرداخت انجام می‌شود و یادآوری برای بیمار ارسال می‌شود.
    • زبان مشترک: استفاده از اصطلاحاتی مانند “رزرو وقت”، “لغو ویزیت”، “یادآوری وقت” در کد و مستندات، به‌جای اصطلاحات مبهم یا غیراستاندارد.

    اهمیت Domain Discovery
    کشف دامنه (Domain Discovery) فرآیند درک عمیق نیازها، فرآیندها و پیچیدگی‌های کسب‌وکار است. اهمیت آن به شرح زیر است:
    • درک بهتر کسب‌وکار: کشف دامنه به توسعه‌دهندگان کمک می‌کند تا نیازهای واقعی کاربران (مثل پزشکان و بیماران) را درک کنند.
    • ایجاد زبان مشترک: با استفاده از Ubiquitous Language، سوءتفاهم بین تیم فنی و غیرفنی کاهش می‌یابد.
    • طراحی مدل قوی: کشف دامنه به شناسایی موجودیت‌ها، رویدادها و Aggregates کمک می‌کند که منجر به طراحی Rich Domain Model می‌شود.
    • کاهش خطاها: با مدل‌سازی دقیق فرآیندهای کسب‌وکار، احتمال خطا در پیاده‌سازی کاهش می‌یابد.
    • انعطاف‌پذیری در برابر تغییرات: یک مدل دامنه خوب طراحی‌شده، سیستم را برای تغییرات آینده آماده می‌کند.

    مثال در سیستم رزرو وقت: بدون کشف دامنه، ممکن است توسعه‌دهندگان فرض کنند که رزرو وقت فقط شامل ثبت زمان است، درحالی‌که در دنیای واقعی، نیاز به بررسی در دسترس بودن پزشک، ارسال یادآوری و مدیریت پرداخت نیز وجود دارد. کشف دامنه این جزئیات را روشن می‌کند. با استفاده از کشف دامنه و طوفان فکری، می‌توان سیستم‌هایی مانند رزرو وقت ویزیت را با دقت مدل‌سازی کرد. این فرآیند به شناسایی رویدادها، فرمان‌ها و موجودیت‌ها کمک می‌کند و زبان مشترکی برای تیم ایجاد می‌کند. کشف دامنه نه‌تنها به طراحی بهتر نرم‌افزار کمک می‌کند، بلکه تضمین می‌کند که سیستم با نیازهای واقعی کسب‌وکار هم‌خوانی دارد.
    • سید امید موسوی در ۱۴۰۴/۰۵/۲۹ ۱۴:۰۳
      چرا بیمار، پزشک جداگانه Aggregate مستقل نیستند؟

      در طراحی اولیه سیستم‌های رزرو وقت ، تمرکز اصلی روی "نوبت گرفتن" است؛ یعنی فرآیند رزرو بنابراین ساختار Aggregateها بر اساس عملیات اصلی کسب‌وکار (Booking) شکل می‌گیرد.

      1) معیار اصلی: تراکنش و تغییرات همزمان (Consistency Boundary)

      در Aggregate، همه چیزهایی باید باشند که با هم و در یک تراکنش تغییر می‌کنند.
      • وقتی یک Appointment ایجاد یا لغو می‌شود، ما باید ID پزشک و ID بیمار را داشته باشیم، ولی اطلاعات کامل بیمار، پزشک را داخل این تغییر نمی‌دهیم.
      • بیمار یا پزشک ممکن است اطلاعات‌شان (مثل آدرس، تخصص، تغییر نام) در زمان دیگری تغییر کنند، و این ربطی به عملیات رزرو ندارد.
      پس نیازی نیست بیمار، پزشک بخشی از Aggregate Appointment باشند.

      2) Aggregateهای بیمار(Patient) و پزشک( Doctor) ممکن‌اند بعداً ساخته شوند

      اگر سیستم بزرگ‌تر شود و بخواهیم:
      • مدیریت پرونده پزشکی بیمار
      • یا مدیریت شیفت و برنامه‌ پزشک
      آن موقع ممکن است بیمار، پزشک هر کدام Aggregate مستقل بشوند با منطق داخلی خودشان.
      ولی در سیستم ساده‌ی رزرو:
      • ما فقط به عنوان Reference به آن‌ها نیاز داریم
      • پس Aggregate ساختن برایشان فقط پیچیدگی اضافه است

      3) Rule: "Only include what you need to enforce invariant"

      Invariant یعنی قانونی که باید همیشه در این Aggregate درست باشد.
      • قانون اصلی در Appointment:
      • "یک پزشک نمی‌تواند همزمان دو نوبت داشته باشد"
      • این قانون فقط بر اساس ID پزشک قابل کنترل است. نیاز نداریم تمام شیء Doctor را داخل Aggregate داشته باشیم.
      بنابراین:
      بیمار، پزشک موجودیت هستند، اما Aggregateشان جدا نیست چون منطق هماهنگی زمانی و تجاری در بخش Appointment مدیریت می‌شود، نه در بخش بیمار، پزشک


  • وحید نصیری در ۱۴۰۴/۰۵/۲۹ ۱۰:۵۵
    مثالی از کشف دامنه و Event Storming، با یک مثال ملموس: سیستم پرداخت شارژ آپارتمان

    مرحله ۱: کشف دامنه با طوفان فکری
    فرض کنیم شما و چند عضو تیم در ابتدای طراحی یک سیستم مدیریت شارژ ساختمان پشت یک تخته سفید ایستاده‌اید. بدون هیچ کدی، فقط با یک سوال ساده شروع می‌کنیم:
    «در دنیای واقعی چه اتفاقاتی (رویدادها) رخ می‌دهد؟»

    گام اول: شناسایی رویدادها (Domain Events)
    در ابتدا فقط می‌خواهیم وقایع قابل مشاهده دنیای واقعی را “روی تخته” لیست کنیم:
    • قبض شارژ برای واحد صادر شد
    • مالک قبض را مشاهده کرد
    • مالک قبض را پرداخت کرد
    • مهلت پرداخت تمام شد
    • تأخیر در پرداخت ثبت شد

    در این لحظه، هیچ حرفی از «کلاس»، «جدول دیتابیس» یا «EF-Core» نیست. فقط وقایع.

    گام دوم: شناسایی فرمان‌ها (Commands)
    حالا از خودمان می‌پرسیم:
    «چه اقدامی باعث رخ دادن هر کدام از این رویدادها می‌شود؟»
    • صادر کردن قبض شارژ (IssueChargeBill)
    • مشاهده قبض (ViewChargeBill)
    • پرداخت قبض (PayChargeBill)
    • محاسبه جریمه تأخیر (CalculateLatePenalty)

    این‌ها فرمان‌هایی هستند که باعث تولید رویداد می‌شوند.

    گام سوم: شناسایی موجودیت‌ها و Aggregates
    تا این‌جا رویداد و فرمان داریم، پس باید ببینیم این‌ها مربوط به چه موجودیت‌هایی هستند:

    رویداد / فرمان موجودیت مرتبط
    صادر کردن قبضBuilding / Unit
    پرداخت قبضChargeBill
    تأخیر در پرداخت ثبت شدChargeBill
    محاسبه جریمهChargeBill
    در نتیجه برای این دامنه، موجودیت‌های اصلی ما می‌توانند شامل شوند:
    • Building (ساختمان)
    • Unit (واحد)
    • ChargeBill (قبض شارژ)

    در این مرحله ممکن است متوجه شویم که ChargeBill به‌عنوان Aggregate Root رفتار می‌کند، زیرا اکثر فرمان‌ها و رویدادها حول آن شکل می‌گیرند.

    مرحله ۲: ترسیم مدل و زبان مشترک (Ubiquitous Language)
    در این مرحله، واژه‌هایی که در جلسه طوفان فکری استفاده کرده‌ایم، کم‌کم تبدیل به زبان مشترک تیم می‌شوند. یعنی همه اعضای تیم — چه توسعه‌دهنده، چه تحلیل‌گر، چه تیم پشتیبانی — وقتی می‌گویند «پرداخت قبض شارژ»، دقیقاً منظورشان همان PayChargeBill است که باعث رخ دادن ChargeBillPaid می‌شود. برای روشن‌تر شدن مسیر، می‌توان گفتگو با تیم را به‌صورت زیر در ذهن مجسم کرد:
    🗣️ «اگر تاریخ پایان سررسید گذشته باشد، چه اتفاقی می‌افتد؟»
    🔎 – “رویداد LatePaymentRegistered رخ می‌دهد، چون مهلت پرداخت تمام شده”.
    🗣️ «چه کسی این رویداد را ایجاد می‌کند؟»
    🔎 – “فرمان CalculateLatePenalty روی موجودیت ChargeBill اجرا می‌شود”.

    بدون اینکه متوجه شویم، عملاً داریم مدل دامنه را شکل می‌دهیم.

    جمع‌بندی (به زبان مدل‌سازی)
    مرحلهخروجی
    شناسایی رویدادهاChargeBillIssued, ChargeBillPaid, …
    شناسایی فرمان‌هاIssueChargeBill, PayChargeBill, …
    شناسایی موجودیت‌هاBuilding, Unit, ChargeBill
    شکل‌گیری زبان مشترک (UL)«قبض شارژ»، «محاسبه جریمه»، «پرداخت»، …