علیرضا ارومند
علیرضا ارومند
خواندن ۸ دقیقه·۵ سال پیش

فصل دوم Clean Architecture - داستان دو ارزش!!!

1. مقدمه:

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

2. عملکرد:

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

اگر برنامه آنطوری که مورد انتظار است کار نکند، تیم توسعه شروع به دیباگ برنامه می‌کند تا خطای موجود در سیستم را پیدا نموده و آن را مطابق با نیازمندی مورد انتظار اصلاح می‌کند.

اغلب مهندسین نرم‌افزار به این مرحله از کار به عنوان کل کار خود نگاه می‌کنند. آن‌ها گمان می‌کنند اینکه کدی بنویسند که ویژگی‌های مورد انتظار را پیاده کند و در صورت وجود مشکل آن‌را دیباگ کنند کل کاری است که باید یک توسعه دهنده انجام دهد. اما متاسفانه اشتباه می‌کنند.

3. معماری:

دومین ویژگی‌ با ارزش یک سیستم نرم‌افزاری را باید در کلمه نرم‌افرار جستجو کنیم. در حقیقت این کلمه از ترکیب دو کلمه "نرم" و "افزار" یا "ابزار" تشکیل شده است. تکلیف قسمت دوم یعنی "افزار" که معلوم است و اشاره به یک محصول می‌کند. اما ارزش دوم در دل کلمه "نرم" نهفته است.

اگر در لغت‌نامه دهخدا یا عمید جستجو کنیم معانی "رقیق، سست، آرام، آهسته، لطیف" را برای کلمه "نرم" خواهیم یافت. خوب این لطافت و نرم بودن باید در همه جنبه‌های این ابزار وجود داشته باشد و مهم ترین جنبه‌ای که باید با مفهوم نرم بودن هم‌خوانی داشته باشد، قابلیت تغییر عملکرد سیستم به سادگی و لطافت و نرمی است. مسلما اگر قرار بود تغییرات در عملکرد سیستم به سختی اتفاق بیافتد به جای نام نرم‌افزار از نام سخت‌افزار استفاده می‌کردیم.

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

این تفاوت بین شکل و اندازه تغییرات است که معمولا هزینه تولید نرم‌افزار را به مرور افزایش می‌دهد. به همین دلیل است که بعضا تغییرات بدون در نظر گرفتن اندازه آن‌ها هزینه تولید نرم‌افزار را افزایش می‌دهند. به همین دلیل است که هزینه تولید نرم‌افزار در اوایل عمر آن کمتر از سالهای بعدی آن است.

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

شاید استفاده از کلمه "شکل" در این مطلب کمی دور از انتظار باشد، اما در نهایت نتیجه خوبی از این استفاده خواهیم گرفت. اگر دقت کنید اغلب توسعه دهندگان این تصور را دارند که کاری نامتعارف انجام می‌دهند. مثلا قرار است یک تیرآهن مستطیل شکل را در فضای یک میل‌گرد جای دهند.

مسئله اساسی معماری سیستم‌ها است. هنگامی که معماری‌ سیستم، شکل خاصی را بر دیگری ترجیح می‌دهد، تغییر در شکل سیستم و نیازمندی‌ها سخت‌تر می‌شود. در نتیجه معماری سیستم باید جدای از شکل انجام کار‌ها باشد.

4. ارزش بیشتر:

بودن یا نبودن مسئله این است. معماری یا عملکرد؟ کدام یک برای یک سیستم نرم‌افزاری مهم‌تر است؟ ارائه عملکرد درست برای یک سیستم نرم‌افزاری مهم‌تر است یا قابلیت تغییر ساده‌تر؟

قاعدتا اگر این سوال را از مدیران کسب و کار بپرسید بی درنگ به شما پاسخ می‌دهند مهم این است که سیستم باید به درستی کار کند. اما توسعه دهندگان معمولا با این نظریه مشکل دارند و مخالف این نظر هستند. بیایید با یک مثال دقیق‌تر این موضوع را بررسی کنیم.

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

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

اگر از مدیران کسب و کار بپرسید " آیا می‌خواهید بعدا در سیستم تغییر ایجاد کنید؟" به شما پاسخ خواهند داد: "بله قطعا تغییرات خواهیم داشت". اما اگر کمی با آن‌ها کلنجار بروید به شما خواهند گفت که عملکرد حال حاضر مهم‌تر از انعطاف سیستم برای پذیرش تغییرات آینده است. در همین شرایط اگر آن‌ها از شما بخواهند تغییری در سیستم اعمال کنید و شما تخمین زمان و هزینه زیادی برای سیستم داشته باشید آن‌ها عصبانی خواهند شد و به شما خواهند گفت که چرا اجازه دادید کار سیستم به جایی برسد که انجام یک تغییر ساده اینقدر هزینه‌بر باشد.

5. ماتریس آیزنهاور:

رئیس‌جمهور سابق ایالات متحده آمریکا، جناب دوایت دی. آیزنهاور
رئیس‌جمهور سابق ایالات متحده آمریکا، جناب دوایت دی. آیزنهاور

در سال ۱۹۵۴ (۱۳۳۳ هجری شمسی) رئیس‌جمهور سابق ایالات متحده آمریکا، جناب دوایت دی. آیزنهاور، در جریان یک سخنرانی بین‌المللی حرف جالبی زد. مضمون سخنان آیزنهاور این بود: «مشکلات من دو نوعند: فوری‌ها و مهم‌‌ها. فوری‌ها مهم نیستند، و مهم‌ها هم هیچگاه فوری نیستند.»

برای درک بهتر این صحبت ماتریسی مانند شکل زیر در نظر می‌گیریم:

با کمی دقت در این سخن قدیمی، به نکات ارزشمندی دست می‌یابیم. کارهایی که فوری هستند معمولا مهم نسیتند و کارهایی که مهم هستند به ندرت فوری هستند. قطعا در این بین کارهایی هم وجود دارند که شرایط متفاوتی دارند یعنی کارهایی که فوری و مهم هستند و کارهایی که غیرفوری و بی اهمیت هستند.

اگر بخواهیم این 4 حالت را در یک لیست مرتب قرار دهیم، این لیست به شرح زیر خواهد بود:

  • مهم و فوری
  • مهم و غیرفوری
  • غیرمهم و فوری
  • غیرمهم و غیر‌فوری

ارزش اولی که برای یک سیستم‌ نرم‌افزاری بیان کردیم یا همان عملکرد آن‌ها یک نیاز فوری است و ارزش دوم آن یعنی معماری و قابلیت تغییر آن بسیار مهم است. در لیست بالا کارهای مهم رتبه 1 و 2 را به خود اختصاص داده‌اند و کارهای فوری رتبه‌های 1 و 3.

یکی از بزرگترین ایراداتی که مدیران و ذینفعان کسب و کارها انجام می‌دهند این است که کارهایی که در رده سوم قراردارد یعنی غیرمهم و فوری را به مرتبه یک یعنی مهم و فوری ارتقا می‌دهند. این جابجایی باعث می‌شود کارهایی که مربوط به معماری در رتبه دوم می‌شود یعنی مهم و غیرفوری دائما به تاخیر بیافتد و کارهایی که اهمیت انجام کمی دارد دائم به پروژه اضافه بشود.

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

6. جنگ برای معماری:

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

یک تیم توسعه موفق به خوبی از پس این کشمکش برخواهد آمد. نکته ای که به عنوان یک مهندس نرم‌افزار باید همیشه در ذهن خود داشته باشیم این است که ما کارمند ذینفعان پروژه نیستیم، بلکه ما خودمان یکی از ذینفعان پروژه هستیم. ما نیز در پروژه‌ها سهیم هستیم و باید از ارزش سهام خودمان در پروژه‌ها دفاع کنیم. این بخشی از وظیفه و نقش ما به عنوان مهندس نرم‌افزار است.

در پایان به این نکته دقت داشته باشید که اگر ابتدا سیستم را توسعه دهید و بعد از مدتی به سراغ ایجاد یک معماری برای آن بروید، احتمالا توسعه و تغییر سیستم بسیار پرهزینه خواهد بود. اگر در سیستمی که به این شکل توسعه داده شده است کار می‌کنید به این معنا است که آنچنان که شایسته و لازم بوده است برای حفظ حقوق خود در پروژه مبارزه نکرده اید.

software architectureclean architectureclean code
شاید از این پست‌ها خوشتان بیاید