مدل نرمافزار یه گفتوگوی دائمیه، هم با آدمای متخصص حوزه (خبرگان دامنه) و هم با خود کد
طراحی نرمافزار بر پایهی مدل، قلب ماجرای DDD محسوب میشه. مدل صرفاً یه نقشه یا دیاگرام نیست؛ بلکه عنصری زنده و فعال در کل فرایند طراحی و توسعهست. مهمتر از همه، ما فقط راهحل رو مدل نمیکنیم، بلکه خودِ مسئله رو مدل میکنیم.
از نگاه من، مدل یه درک مشترک به تصویر کشیده شده است که بین همهی کسانی که در ساخت نرمافزار نقش دارن شکل میگیره – از متخصصان کسبوکار و مالک محصول گرفته تا برنامهنویسها. این مدل باید طوری ساخته بشه که هم برای انسانها قابل فهم باشه و هم راحت به کد تبدیل بشه. مثلاً ممکنه از نمودارهای ساده یا دیاگرامهایی شبیه UML استفاده کنیم، ولی خشک و رسمی نه؛ بیشتر یه ابزار منعطف برای فهم بهتر.
مدل یه چیز ایستا و ثابت نیست که از اول کامل مشخص بشه. بیشتر شبیه یه چیز «بهموقع» (Just-In-Time) که توی مسیر توسعه و گفتوگو با متخصصان کمکم شکل میگیره و پخته میشه.
مدل چیه؟ چند مثال برای درک بهتر:
- توی یه سیستم فروشگاه آنلاین، مدل میتونه شامل مفاهیمی مثل «سبد خرید»، «محصول»، «سفارش» و «پرداخت» باشه و روابط بین این مفاهیم رو نشون بده.
- توی نرمافزار کتابخانه، مدل میتونه تعریف کنه که «کتاب»، «عضو»، «امانت» و «رزرو» چه ویژگیهایی دارن و چطور به هم وصل میشن.
- توی یه سیستم بیمه، مدل ممکنه شامل «پوشش بیمه»، «مطالبه»، «ارزیابی خسارت» و «مشتری» باشه، با قوانین و محدودیتهایی که توی دنیای واقعی وجود داره.
این مدل هم باید از متخصصان یاد بگیره، هم از کد. چون وقتی شروع میکنیم به پیادهسازی، ممکنه یه مفهومی که تو مدل ساده بود، توی کد خیلی پیچیدهتر یا حتی غیرعملی دربیاد. اونوقت باید مدل رو بازبینی کنیم.
در واقع، طراحی نرمافزار یه گفتوگوی دائمیه بین زبان و مدل. زبانی که استفاده میکنیم (چه تو صحبت، چه تو داکیومنت و چه توی کد) مستقیماً رو مدل تأثیر میذاره. و برعکس، وقتی مدل پیچیدهتر میشه، مجبور میشیم زبان دقیقتری انتخاب کنیم تا مفهوم رو درست منتقل کنیم.
اما این گفتوگو فقط بین زبان و مدل نیست. مدل نرمافزاری مدام با متخصصان دامنه و با کد در حال صحبت کردنه. باید واقعیات دنیای بیرونی رو از متخصصان بگیره، و در عین حال بتونه قابل پیادهسازی هم باشه. این دو تا مکالمه کمک میکنن که هم مسئلهی درستی حل بشه، هم راهحل قابل اجرا و نگهداری باشه.
ما میتونیم این چهار مؤلفه [زبان، مدل، متخصصان دامنه، و کد] رو به عنوان «چهار ضلع طراحی نرمافزار» ببینیم. هر کدوم یه دید و نقش مهم دارن.

ضلع حیاتی: گفتوگو با متخصصان دامنه
فرض کن بخوای یه ابزار برای دکترها بسازی بدون اینکه با هیچ دکتری حرف بزنی. احتمالاً چیزی میسازی که از نظر فنی عالیه ولی اصلاً به درد دکترها نمیخوره. اینجاست که گفتوگو با متخصصان دامنه خیلی مهمه.
اینا همون آدمهایی هستن که هر روز با مسئله سروکار دارن. مدل نرمافزاری ما باید از دل همین درک ساخته بشه. نه صرفاً با گرفتن یه لیست از نیازمندیها، بلکه با گفتوگوی عمیق و مداوم برای فهم مفاهیم کلیدی، روابط بین اجزا، و قوانین نانوشتهی اون دنیا.
کشف نیاز واقعی: از دل این گفتوگوهاست که نیازهای پنهان و دردهای واقعی کشف میشن. مثلاً ممکنه یه درخواست ساده، پشتش کلی منطق و استثنا داشته باشه که فقط توی صحبت روشن میشن.
ساختن یه زبان مشترک: توی این مسیر، یه واژگان مشترک شکل میگیره که هم توی مدل و هم حتی توی کد بازتاب پیدا میکنه. این همون «زبان فراگیر» یا Ubiquitous Language ـه که همهی تیم – از برنامهنویس گرفته تا متخصص دامنه – باید ازش استفاده کنن.
درک تدریجی: مدل یه چیزیه که وسط گفتوگو شکل میگیره، نه قبلش. هرچی بیشتر حرف میزنیم، سؤال میپرسیم و توضیح میشنویم، فهم ما بهتر میشه و مدل دقیقتر در میاد.
مثال: برای نرمافزار کتابخانه، صحبت با کتابدار فقط این نیست که بپرسیم “چه ویژگیهایی میخواید؟” بلکه باید بفهمیم چطوری کتابها رو دستهبندی میکنن، انواع امانت چطوره، فرآیند رزرو از نگاه اونها چجوریه، و با آیتمهای برگشتی چطور برخورد میکنن. همهی اینا کمک میکنه مدل نرمافزاری واقعیتر و کاربردیتر بشه.
ضلع ساکت: گفتوگو با خود کد
یه ضلع مهم دیگه از طراحی نرمافزار، گفتوگو با خود کده. وقتی مدل رو به یه سیستم واقعی تبدیل میکنیم، کد میتونه کلی چیز بهمون نشون بده – پیچیدگیهایی که ندیده بودیم یا درک اشتباهی که داشتیم.
کشف چالشهای پیادهسازی: گاهی یه مفهوم تو مدل خیلی سادهست، ولی وقتی میخوایم پیادهش کنیم، میبینیم خیلی پیچیده یا حتی غیراصولیه. این باعث میشه دوباره برگردیم و مدل رو بازبینی کنیم.
آشکار شدن فرضیات پنهان: حین کدنویسی ممکنه بفهمیم مدل ما یه فرضی گرفته که همیشه درست نیست. اینجاست که باید مدل رو دقیقتر کنیم.
راهنمایی برای بهبود مدل: گاهی هم کد بهمون میگه که یه سری مفاهیم بهتره با هم گروه بشن یا ارتباط خاصی دارن که تو مدل اولیه مشخص نشده بود.
کدِ دیروز، مانعِ امروز: یه قسمت از کد ممکنه تو گذشته خوب جواب میداده، ولی الان مانع اضافه کردن یه ویژگی جدید شده. یعنی راهحلهای دیروز ما، بخشی از کانتکست مسئلهی امروز میشن. پس باید مدام با این کد حرف بزنیم و بفهمیم چی از قبل داریم، چه فرضهایی توش هست، و کجا لازمه مدل و کد هر دو تغییر کنن.
مثال: تو نرمافزار کتابخانه، ممکنه اول فکر کنیم که وضعیت کتاب فقط یه بولین باشه (موجود/ناموجود). ولی وقتی میخوایم منطق امانت و رزرو رو پیاده کنیم، میفهمیم باید بدونیم کتاب دقیقاً کجاست (روی قفسه، امانت داده شده، در صف رزرو، در تعمیر و…) و حتی کی اون رو داره. این باعث میشه مدل وضعیت کتاب غنیتر بشه.
نبض تکرارشوندهی بهبود مدل
مدل یه چیز ثابت نیست که یه بار طراحی بشه و تموم. توی مسیر پروژه، با فهم بهتر دامنه و پیچیدگیهای اجرا، درک ما از مسئله تغییر میکنه. پس مدل هم باید تغییر کنه.
این تغییرات لزوماً بازنویسی کامل نیست؛ بیشتر شبیه یه سری اصلاح، شفافسازی یا حتی بازتعریفهای کلیدی هستن. گاهی ویژگی جدیدی میخوایم اضافه کنیم که پیچیدگی جدیدی رو آشکار میکنه. گاهی هم از دل کد، یه مسیر سادهتر پیدا میکنیم که مدل قبلی نداشته.
قدرت حلقههای بازخورد
در قلب این بهبود مستمر، حلقههای بازخورد قرار دارن. گفتوگو با متخصصان فقط مال جلسههای اولیه نیست. وقتی نسخه اولیهی نرمافزار رو نشون میدیم، بازخوردشون کمک میکنه بفهمیم آیا نرمافزار مطابق درک اونهاست یا نه.
از اون طرف، خودِ کد هم بازخورد میده: آیا مدل به راحتی به کد تبدیل میشه؟ یا یه جاهایی پیچیدگی یا تناقض ایجاد کرده؟ این نکتهها هم باید توی بازطراحی مدل لحاظ بشن.
در نهایت، پایداری و موفقیت یه نرمافزار وابسته به کیفیت این گفتوگوهای مداومه. زبانی شفاف و منسجم، مدلی قوی میسازه؛ و مدلی که بین دانش دامنه و کد پل میزنه، راه رو برای یه پیادهسازی موفق باز میکنه.
پس مدل فقط یه نمودار یا ابزار طراحی نیست – این همون پایهی اصلیه که نرمافزارهای خوب روش بنا میشن.