نویسنده: اریک ایوانس (Eric Evans)
سال انتشار: ۲۰۰۳
تعداد صفحات: ۵۶۰ صفحه
ژانر: معماری نرمافزار، طراحی سیستم، مهندسی دامنه
سطح مطالعه: متوسط تا پیشرفته (حداقل ۲ سال تجربه عملی کدنویسی توصیه میشود)
چرا این کتاب؟ چرا حالا؟
تا به حال برایتان پیش آمده که ماهها روی یک پروژه نرمافزاری کار کنید، اما در میانه راه متوجه شوید که تیم فنی و تیم بیزنس اصلاً به یک زبان صحبت نمیکنند؟ یا کدی بنویسید که از نظر فنی کاملاً درست است، اما نیاز واقعی کاربر را برآورده نمیکند؟ یا سیستمی را تحویل دهید که بعد از شش ماه، هیچ کس جرأت تغییر دادن آن را ندارد؟
کتاب Domain-Driven Design نوشته اریک ایوانس، دقیقاً همان پلی است که این شکاف را پر میکند. این کتاب در سال ۲۰۰۳ منتشر شد، اما مفاهیم آن نه تنها کهنه نشده، بلکه با ظهور معماری میکروسرویسها و سیستمهای توزیعشده، بیش از پیش حیاتی و مدرن شدهاند.
در این معرفی، قصد ندارم صرفاً خلاصهای از کتاب ارائه دهم. میخواهم با شما همراه شوم، از تجربیات خودم بگویم، و نشان دهم که چرا این کتاب برای هر معمار نرمافزاری، چه تازهکار و چه باتجربه، یک ضرورت است.
این کتاب، حاصل سالها تجربه عملی اریک ایوانس در پروژههای نرمافزاری واقعی است. او در مقدمه کتاب میگوید که این کتاب را نه به عنوان یک نظریهپرداز آکادمیک، بلکه به عنوان یک مهندس نرمافزار که در خط مقدم پروژهها بوده، نوشته است. هر مفهوم در کتاب، حداقل یک بار در پروژهای واقعی آزمایش شده و جواب داده است.
معمای اصلی کتاب؛ پیچیدگی از کجا میآید؟
اریک ایوانس در فصلهای ابتدایی کتاب، یک ادعای جسورانه مطرح میکند: دشمن اصلی نرمافزار، پیچیدگی است. اما نه هر پیچیدگی. او پیچیدگی را به دو دسته تقسیم میکند.
دسته اول، پیچیدگی فنی است. همان مسائلی که ما برنامهنویسان با آنها دست و پنجه نرم میکنیم: انتخاب فریمورک مناسب، بهینهسازی پایگاه داده، مدیریت همروندی (Concurrency)، امنیت، و صدها چالش فنی دیگر. این دسته از پیچیدگی، قابل پیشبینی است، کتابهای زیادی برایش نوشته شده، و معمولاً راهحلهای مشخصی دارد.
اما دسته دوم، قاتل اصلی پروژههاست: پیچیدگی دامنه (Domain Complexity). این همان پیچیدگی قوانین بیزنس، روابط بین مفاهیم دنیای واقعی، استثناها، مرزها، و فرآیندهایی است که یک کسبوکار را منحصر به فرد میکنند. سامانه بانکی را در نظر بگیرید. قوانین مربوط به محاسبه سود تسهیلات، مقررات ناظر بر تراکنشهای ارزی، یا فرآیندهای تأیید اعتبار مشتری – اینها چیزهایی نیستند که در یک کتاب برنامهنویسی یاد بگیرید. آنها را فقط از متخصصان آن حوزه میتوان فهمید.
نکته تکاندهنده کتاب این است: تکنولوژی به تنهایی نمیتواند بر پیچیدگی دامنه غلبه کند. میتوانید از بهترین زبانها و بهترین چارچوبها استفاده کنید، اما اگر مدل ذهنی شما از کسبوکار ناقص یا اشتباه باشد، محصول نهایی شکست میخورد. پیچیدگی دامنه، اگر مهار نشود، مانند آب درون یک ترک کوچک عمل میکند: کمکم همه جا را فرا میگیرد و سازه را از درون فرو میریزد.
راهحل ایوانس، همان طور که از نام کتاب پیداست، طراحی مبتنی بر دامنه است. یعنی تمرکز اصلی را روی مدلسازی دقیق هسته کسبوکار بگذاریم، و اجازه دهیم تکنولوژی در خدمت این مدل باشد، نه برعکس.
دو بال پرواز؛ استراتژی و تاکتیک در DDD
یکی از نقاط قوت کتاب، تقسیمبندی آن به دو بخش کاملاً مجزا اما مکمل است: طراحی استراتژیک و طراحی تاکتیکی. بسیاری از کتابهای معماری، فقط بر یکی از این دو جنبه تمرکز میکنند. اما ایوانس به درستی معتقد است که یک معمار نرمافزار باید هم دید کلان داشته باشد، هم بتواند جزئیات را درست پیاده کند.
طراحی استراتژیک (Strategic Design)
بخش استراتژیک کتاب، به مدیریت پیچیدگی در سطح کلان سیستم میپردازد. اینجا دیگر خبری از کلاس و متد نیست. بحث بر سر این است که چگونه یک سیستم بزرگ را به بخشهای کوچکتر و مستقل تقسیم کنیم، مرزهای هر بخش را مشخص کنیم، و نحوه ارتباط بین آنها را تعریف کنیم.
اولین مفهومی که در این بخش با آن روبرو میشوید، زبان مشترک همهجا-یکسان(Ubiquitous Language) است. ایوانز معتقد است که تیم فنی و تیم بیزنس باید زبانی واحد داشته باشند که هم در گفتگوهای روزمره، هم در مستندات، هم در کد، و هم در دیاگرامها جاری باشد. این زبان، نه فقط یک دیکشنری ساده، بلکه یک مدل مفهومی عمیق از کسبوکار است. وقتی یک متخصص بیزنس میگوید «وام»، یک توسعهدهنده نیز دقیقاً همان مفهوم را در کد با کلاس Loan پیاده میکند. هیچ ترجمهای در کار نیست. هیچ کلمه مبهمی وجود ندارد.
دومین مفهوم کلیدی، Bounded Context است. ایوانز با صراحت میگوید که در سیستمهای بزرگ، نمیتوان یک مدل واحد برای همه چیز داشت. هر مدل، در یک مرز مشخص معنادار است. به عنوان مثال، مفهوم «مشتری» در سیستم فروش، در سیستم پشتیبانی، و در سیستم حسابداری ممکن است معانی متفاوتی داشته باشد. تلاش برای یکسان کردن آنها، فقط پیچیدگی را بیشتر میکند. بهتر است هر بافت محدود را مستقل طراحی کنیم و سپس نحوه ارتباط بین آنها را مشخص کنیم.
سومین مفهوم، Context Mapping است. زمانی که بافتهای محدود خود را تعریف کردیم، باید مشخص کنیم که چگونه با یکدیگر تعامل دارند. آیا مستقیماً با یکدیگر ارتباط برقرار میکنند؟ آیا یک لایه واسط (Anti-Corruption Layer) قرار میدهیم تا از ورود مفاهیم بیگانه به مدل اصلی جلوگیری شود؟ آیا یک هسته مشترک (Shared Kernel) تعریف میکنیم که چند بافت محدود از آن استفاده کنند؟ اینها پرسشهایی هستند که پاسخ آنها ساختار کلی سیستم را تعیین میکند.
طراحی تاکتیکی (Tactical Design)
بخش تاکتیکی کتاب، به سطح کد و پیادهسازی میرود. اینجا جایی است که ایوانز نشان میدهد مفاهیم استراتژیک چگونه در عمل پیاده میشوند. برای هر کسی که با الگوهای طراحی (Design Patterns) آشنایی دارد، این بخش آشنا به نظر میرسد، اما ایوانز با نگاهی تازه و متمرکز بر دامنه، این الگوها را بازتعریف میکند.
اولین تمایز مهم، تفکیک بین نهاد (Entity) و شیء مقداری (Value Object) است. یک نهاد، هویت منحصر به فردی دارد و در طول زمان تغییر میکند. مانند یک حساب بانکی که شماره منحصر به فرد دارد و موجودی آن تغییر میکند. اما یک شیء مقداری، فقط با ویژگیهایش شناخته میشود. مانند یک آدرس که اگر دو آدرس از نظر مشخصات یکسان باشند، هیچ تفاوتی با هم ندارند. این تفکیک، مدیریت حافظه و منطق بیزنس را بسیار سادهتر میکند.
دومین مفهوم کلیدی، اگریگیت (Aggregate) است. این یکی از پیچیدهترین مفاهیم کتاب است و بسیاری از خوانندگان در درک آن مشکل دارند. اگریگیت، مجموعهای از اشیاء مرتبط است که به عنوان یک واحد با آنها رفتار میشود. فرض کنید یک سفارش خرید داریم که شامل چندین قلم کالا است. سفارش و قلمهای کالا، یک اگریگیت را تشکیل میدهند. ریشه اگریگیت (Aggregate Root)، همان سفارش است و تنها راه برای دسترسی به قلمهای کالا، از طریق سفارش است. این کار از یکپارچگی دادهها محافظت میکند.
سوم، سرویسهای دامنه (Domain Services) و مخزنها (Repositories) هستند. سرویسهای دامنه برای عملیاتی استفاده میشوند که به یک نهاد یا شیء مقداری خاص تعلق ندارند. مثلاً انتقال وجه بین دو حساب، یک سرویس دامنه است. مخزنها نیز لایه دسترسی به دادهها را انتزاع میکنند، به طوری که لایه دامنه از اینکه دادهها دقیقاً کجا و چگونه ذخیره میشوند، بیخبر میماند.
نظر شخصی من
حالا که مفاهیم اصلی کتاب را مرور کردیم، میخواهم صادقانه با شما صحبت کنم. من این کتاب را سه بار کامل خواندهام. بار اول، تازهکار بودم و بسیاری از مفاهیم برایم مبهم به نظر میرسید. بار دوم، بعد از چند سال تجربه عملی، تازه متوجه عمق حرفهای ایوانز شدم. بار سوم، به عنوان یک معمار نرمافزار که چندین پروژه بزرگ را از صفر تا صد طراحی کرده، با احترام تمام صفحاتش را ورق زدم.
نقطه قوت اصلی کتاب، رویکرد بینرشتهای آن است. ایوانز نه فقط یک مهندس نرمافزار، بلکه یک فیلسوف و یک جامعهشناس خوب است. او میداند که مشکل نرمافزارهای بزرگ، فقط فنی نیست؛ انسانی، ارتباطی و سازمانی هم هست. به همین دلیل، راهحلهایش همیشه چندلایه و واقعگرایانه هستند.
اما صادق باشم، کتاب نقاط ضعفی هم دارد. ساختار کتاب برای یک خواننده تازهکار میتواند گیجکننده باشد. ایوانز گاهی اوقات بیش از حد جزئی میشود و در مثالهای طولانی و تخصصی گم میشوید. همچنین، کتاب بیشتر به زبان جاوا نوشته شده و اگر با اکوسیستم جاوا آشنا نباشید، درک برخی مثالها ممکن است دشوار باشد.
با این حال، هیچ کتاب دیگری نیست که بتواند جای این کتاب را بگیرد. اگر بخواهید فقط یک کتاب در حوزه معماری نرمافزار بخوانید، من بدون لحظهای تردید، این را توصیه میکنم. اما با یک شرط: این کتاب را نخوانید که فقط با مفاهیمش آشنا شوید. آن را بخوانید که در پروژه بعدیتان عملاً از آن استفاده کنید. DDD را نمیتوان فقط با خواندن یاد گرفت؛ باید در عمل، در یک تیم واقعی، با یک پروژه واقعی، آن را تجربه کرد.
این کتاب برای چه کسانی است؟
اگر تازه کار هستید و کمتر از دو سال سابقه برنامهنویسی دارید، صادقانه میگویم که این کتاب هنوز برای شما نیست. ابتدا با مفاهیم پایه شیءگرایی، الگوهای طراحی، و معماری لایهای آشنا شوید. بعد سراغ این کتاب بیایید.
اما اگر توسعهدهنده ارشد هستید و احساس میکنید در جایگاه خود متوقف شدهاید، این کتاب دقیقاً همان چیزی است که نیاز دارید. DDD شما را از سطح کدنویس به سطح معمار ارتقا میدهد. به شما یاد میدهد که فراتر از حلقهها و شرطها را ببینید و به سیستم به عنوان یک موجود زنده نگاه کنید.
اگر معمار نرمافزار هستید و هنوز این کتاب را نخواندهاید، لطفاً همین الان خریداری کنید. شرم آور است که یک معمار، مهمترین کتاب حوزه خود را مطالعه نکرده باشد.
اگر مدیر فنی یا رهبر تیم هستید، این کتاب را به تمام تیم توسعه خود هدیه دهید. یک تیم که DDD را فهمیده باشد، به طرز شگفتانگیزی هماهنگتر و مولدتر از تیمی است که فقط کدنویسی بلد است.
نقل قولهای ماندگار از کتاب
در طول مطالعه کتاب، چند جمله بودند که من بارها و بارها به آنها فکر کردهام. شاید این جملات برای شما هم الهامبخش باشند:
«قلب نرمافزار، توانایی آن در حل مسائل مربوط به دامنه برای کاربرانش است. تمام ویژگیهای دیگر، هر چقدر هم مهم باشند، در خدمت این هدف اصلی هستند.»
«پیچیدگی را نمیتوان حذف کرد. میتوان آن را مدیریت کرد. بهترین راه برای مدیریت پیچیدگی، مدلسازی درست دامنه است.»
«زبانی که در کد استفاده میکنید، باید همان زبانی باشد که متخصصان بیزنس در گفتگوهای روزمره خود استفاده میکنند. اگر این دو زبان متفاوت باشند، شکافی ایجاد میشود که هیچ تکنولوژی نمیتواند آن را پر کند.»
بزرگترین اشتباه در طراحی نرمافزار، تلاش برای ساخت یک مدل واحد برای کل سیستم است. سیستمهای بزرگ، به مدلهای متعدد و بافتهای محدود نیاز دارند.
نظرات بزرگان حوزه نرمافزار درباره این کتاب
مارتین فاولر (نویسنده کتاب Patterns of Enterprise Application Architecture):
این کتاب برای سالها مرجع اصلی طراحی مبتنی بر دامنه باقی خواهد ماند. ایوانز توانسته مفاهیم پیچیده را به زبانی ساده و در عین حال عمیق بیان کند. هر کسی که با سیستمهای پیچیده سروکار دارد، باید این کتاب را در قفسه کتابخانه خود داشته باشد.
رابرت مارتین (Uncle Bob) (نویسنده کتاب Clean Architecture):
DDD یکی از تأثیرگذارترین کتابهایی است که در دهه اخیر در حوزه نرمافزار نوشته شده است. ایوانز به ما یادآوری میکند که نرمافزار، قبل از هر چیز، در مورد حل مسائل انسانی است، نه نوشتن کد.
ونورنون (نویسنده کتاب Implementing Domain-Driven Design):
اریک ایوانز، پدرخوانده DDD است. کتاب او سنگ بنای یک جریان فکری عظیم در صنعت نرمافزار شد. من خودم مدیون این کتاب هستم و بسیاری از مفاهیم کلیدی کارم را از آن یاد گرفتم.
بعد از خواندن این کتاب، چه بخوانیم؟
اگر این کتاب را دوست داشتید و میخواهید دانش خود را در این حوزه عمیقتر کنید، کتابهای زیر را به ترتیب توصیه میکنم:
Implementing Domain-Driven Design نوشته ونورنون: این کتاب مکمل عملی کتاب ایوانز است. اگر ایوانز به دنبال «چرایی» است، ونورنون به «چگونگی» میپردازد. این کتاب پر از کد، مثال و پروژه عملی است و به شما نشان میدهد چگونه DDD را در پروژههای واقعی پیاده کنید.
Patterns, Principles, and Practices of Domain-Driven Design نوشته اسکات میلت و نیک تون: کتابی مدرنتر که DDD را در کنار معماریهای جدید مثل Event Sourcing و CQRS بررسی میکند.
Clean Architecture نوشته رابرت مارتین (Uncle Bob): اگر به بخش تاکتیکی DDD (لایهبندی، اصول معماری تمیز) علاقه داشتید، این کتاب ادامه طبیعی آن است.
سخن پایانی
کتاب Domain-Driven Design، فقط یک کتاب نیست. یک نحوه تفکر است. یک فلسفه برای مواجهه با پیچیدگی. یک دعوت به ساختن نرمافزارهایی که نه تنها کار میکنند، بلکه معنا دارند.
من مسعود بهرامی، بعد از سالها کار عملی در حوزه معماری نرمافزار، میتوانم با اطمینان بگویم که این کتاب یکی از سه کتابی است که اگر الان گم شوند، اول از همه میروم سراغ خرید دوباره آنها. دو کتاب دیگر را در معرفیهای بعدی خواهم گفت.
حالا نوبت شماست. اگر این کتاب را قبلاً خواندهاید، خوشحال میشوم نظرتان را در بخش دیدگاهها با من و دیگران به اشتراک بگذارید. اگر نخواندهاید، همین امروز تهیه کنید و شروع کنید. قول میدهم پشیمان نشوید.
در مسیر معماری نرمافزار، هیچ میانبری وجود ندارد. اما داشتن یک راهنمای خوب، نیمی از مسیر را روشن میکند.
لینکهای سریع:
-
[خرید کتاب از کتابراه]
-
[خرید کتاب از طاقچه]
-
[مشاهده همه کتابهای معرفی شده در کتابخانه معمار]
-
[پیشنهاد کتاب جدید به آکادمی]
این معرفی توسط مسعود بهرامی، معمار نرمافزار و بنیانگذار آکادمی مسعود بهرامی، نوشته شده است. اگر این مطلب برایتان مفید بود، آن را با دوستان خود به اشتراک بگذارید.