آموزش Domain Driven Design. پیچیدگی ها

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

حال قصد داریم در مورد پیچیدگی صحبت کنیم. مفهوم پیچیدگی در دنیای فیزیکی تفاوت چندانی با مفهوم آن در دنیای نرم افزار ندارد. بیشتر نرم افزار ها نوشته می شوند تا با مسائل و مشکلاتی که در دنیای واقعی وجود دارند، سروکار داشته باشند. این مسائل ممکن است در ظاهر ساده به نظر برسند اما در عین حال ذاتا دارای پیچیدگی های خاص خود هستند. بدون شک، پیچیدگی موجود در فضای مساله، در سیستمی که برای حل آن مساله نوشته خواهد شد، تاثیرگذار خواهد بود. تشخیص نوع پیچیدگی که در زمان ساخت نرم افزار با آن درگیر خواهیم بود، اهمیت بسزایی دارد.

انواع پیچیدگی

در سال 1986، Fred Brooks مقاله ای نوشت که در آن پیچیدگی را به دو دسته بندی ضروری (essential) و تصادفی (accidental) تقسیم کرد. پیچیدگی ضروری از دامنه می آید. یعنی آنجا که خود مساله وجود دارد (problem space). این نوع پیچیدگی نمی تواند کاهش پیدا کند مگر با کسر بُعد خود مساله. در مقابل، پیچیدگی تصادفی از خود راه حل (solution space)، به راه حل افزوده میشود. این پیچیدگی می تواند شامل یک فریمورک، یک دیتابیس یا زیرساخت های دیگر باشد.

سطح پیچیدگی تصادفی با بلوغ هرچه بیشتر صنعت نرم افزار، کاهش می یابد. زبان های برنامه نویسی سطح بالا و ابزارهای مختلفی که وجود دارد، باعث می شود برنامه نویسان وقت بیشتری را صرف فضای مساله (problem space) نمایند. اما همانطور که اشاره شد، اکنون پس از 30 سال، هنوز صنعت درگیر پیچیدگی های تصادفی است. ما ابزارهای قدرتمندی در اختیار داریم اما اکثر این ابزارها، خود نیازمند صرف زمان برای یادگیری هستند. نویسنده اشاره می کند که سالها پیش قطعه کدی به زبان Java Script نوشته بود. وقتی با Angular آشنا شد که چقدر بهتر آن کار را انجام می دهد، به سمت بازنویسی توسط Angular رفت. اما پس از مدتی دریافت که زمان بیشتری در نهایت صرف شد، چرا که یادگیری و چگونگی استفاده از Angular خود یک چالش بزرگ بود.

بعنوان مثال دیگر، با وجود کانتینرها، میزبانی و استقرار اپلیکیشن ها ساده تر شد، اما در عین حال به یک Orchestration هم نیاز داریم و پس از مقداری یادگیری جدید، در میابیم که Kubernetes چه کمک بزرگی می تواند به ما کند. اینجاست که درگیر نوشتن YAML می شویم! تمام زمانی که در این مسیر صرف شد، می توانست درگیر نوشتن خود پروژه و حل مساله اصلی شود.

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

رشد پیچیدگی در گذر زمان
رشد پیچیدگی در گذر زمان


همانطور که در نمودار مشخص شده است، در گذر زمان، پیچیدگی های ضروری کاهش می یابند و پیچیدگی های تصادفی افزایش. ممکن است برای شما تعجب برانگیز باشد که با گذر زمان، پیچیدگی های ضروری تقریبا شیب صفر می گیرند (افزوده نمی شوند)، اما پیچیدگی های تصادفی حتی با شیب تندتر از قبل در حال افزوده شدن هستند. چطور این اتفاق رخ می دهد؟ قطعا ما زمان برای افزودن پیچیدگی تصادفی صرف نمی کنیم.

زمانی که سیستم به مرور برجسته تر می شود، تلاش های فراوانی انجام می شود و کدهای پشتیبان افزایش می یابند، تا باعث شوند فقط سیستم بعنوان یک کل، کار کند. مثلا سیستم cache را پیاده سازی می کنیم، تلاش می کنیم عملکرد کوئری ها را بهبود دهیم، دیتابیس ها را تفکیک یا مرج می کنیم و ...

در نهایت ممکن است ما تصمیم بگیریم پیچیدگی های ضروری را کاهش دهیم تا سیستم بدون مسائل جانبی فراوان، فقط درست کار کند.

اما DDD به شما کمک می کند که بر روی مسائل پیچیده ای که در دامین وجود دارد (پیچیدگی های ضروری) تمرکز کنید. قطعا استفاده از ابزار های جدید فرانت اند یا استفاده از یک دیتابیس دایکیومنت کلود جذابیت دارد، اما بدون درک مشکلی که واقعا می خواهیم آن را حل کنیم، ممکن است این موارد فقط اتلاف وقت محسوب شود. DDD چندین تکنیک سودمند برای مدیریت پیچیدگی ها بوسیله تفکیک سیستم به بخش های کوچک تر ارائه می دهد که هر کدام از این بخش ها برای حل مجموعه ای از مشکلات مرتبط ایجاد می شوند. در بخش های آینده این تکنیک ها به تفصیل تشریح خواهند شد.

با یک حساب سر انگشتی، اینطور می توان گفت:

ضروریات (پیچیدگی های موجود در دامین) را در آغوش بگیرید و پیچیدگی های تصادفی را کاهش دهید. وظیفه شما، افزودن پیچیدگی های تصادفی نیست. در غیر این صورت احتمال افتادن در چاه over-engineering برای شما بالا خواهد رفت.