پیچیدگی زبان طبیعت است که به صورت الگوها، فراکتال ها و تقارن گفته می شود!

خوب مسافران عزیز کاپیتان صحبت میکنه! نوشیدنی مجاز مورد علاقه رو بزنید بر بدن و بشینید روی صندلی هاتون که میخوایم پروازی داشته باشیم به سمت پیچیدگی🤓

در پست قبل قصه به اونجایی رسید که چهار ویژگی ذاتی نرم افزار رو به صورت کلی بررسی کردیم و امروز میخوایم بریم سمت موردی که همه گیر و گرفتاری ما از اون بخش شروع میشه و اون چیزی نیست جزء پیچیدگی 👾💀☠😈

گویند پیچیدگی نرم افزار با پیچیدگی سیستم های طبیعی، سیستم های فیزیکی و سیستم های ساخت بشر کاملا متفاوت هست به این علت که نرم افزار یک محصول طبیعی و زاییده فکر انسان هست، میان عناصر اولیه آن قوانین بنیادی حاکم نیست در صورتی که عناصر اولیه ساخت بشر از قوانین معینی پیروی میکنن ( مثل قوانین فیزیک) از این رو برای سیستم های نرم افزاری ساخت بشر نمی توان هماننده سیستم های طبیعی مدل های ساده در نظر گرفت ( به به چه می گویند🫡)

اما یه سوال مهم: چرا پیچیدگی عین سایه به دنبال مهندسی نرم افزار (و یا بلعکس🙄) هست؟ قبل جواب به این سوال بهتره یه ذره بین برداریم و عوامل پیچیدگی ذاتی نرم افزار  رو از نزدیک بررسی کنیم.

پیچیدگی ذاتی به 4 دسته اصلی تقسیم میشه که عبارتند از:

1)  پیچیدگی دامنه مسئله:

در اغلب اوقات دامنه مسئله ای که نرم افزارمون به حل اون می پردازده پیچیده هست و نیازمندی های گوناگون و حتی متضادی در آن وجود داره، فرض کنیم قراره نرم افزار برای یه شرکت تولیدی و پخش بنویسیم اول از همه نیازمند درک کامل مباحث Functional requirement  توی مسئله هستیم حالا اگر به این نیازمندی Non-Functional requirement رو هم اضافه کنیم مسئله پیچیده تر میشه و حالا به این قضیه ناتوانی کاربر و مهندس نرم افزار رو در درک صحیح یکدیگر رو اضافه کنیم میبینیم چه آشفته بازاری میشه ( برای همین به طور مثال در DDD موضوع ubiquitous language مهمه!!!).

در بیشتر مواقع کاربران و توسعه دهندگان حرف های هم رو به خوبی متوجه نمیشن🤷‍♂️ و این ناشی از بی خبری آنها از زمینه کاری یکدیگر هست چون هر دو زاویه نگاه متفاوتی (در رابطه با زاویه نگاه در پست های آینده حتما این موضوع رو بررسی میکنم) به ماهیت مسئله دارن و همین باعث نظرات متفاوت درباره راه حل های ارائه شده میشه (به نظرم هرچی توسعه دهنده به سمت خبره شدن در دامنه مسئله بره، تصمیماتی با رنگ و بوی  آزمون و خطا کمتر میشه😎).

همچنین اگه یادشتون باشه تو پست قبل گفتم تغییر نیازمندی های سیستم در زمان توسعه و یا بعد از آن در افزایش پیچیدگی سهم بسزایی داره پس مشاهده یه نمونه اولیه یا prototype و مستندات طراحی و سپس استفاده از سیستم بعد از راه اندازی (در این مورد من خودم بارها شاهد این بودم که فاصله توسعه تا لانچ زیاد یا زودهنگام بوده😑😶‍🌫️) آن باعث میشه کاربر به نیازمندی های واقعی خودش پی ببره و درک بهتری از سیستم بدست بیاره ( نگاه iteration میتونه مثال خوبی برای این قضیه باشه).

2) دشواری مدیریت فرایند تولید:

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

3) انعطاف پذیری نرم افزار:

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

همچنین باید این نکته رو مدنظر داشت که سلیقه افراد صاحب کسب و کار دارای یک استاندارد واحد نیست. (بارها دیدیم هرکسی فرود میاد رو سیستم یه نظریه جدیدی میده🙄)

 

4) مشکلات توصیف سیستم های گسسته:

بچه های رشته نرم افزار میدونن که موضوع گسسته جز لاینفک این رشته هست اما موضوع گسسته چیست و چی از جون ما میخواد؟ (والا هی یه موضوعی میاد وسط کشتی ما رو ایلماز!!!😒)

به لحاظ رفتاری میتونیم سیستم ها رو به دو گروه گسسته و پیوسته تقسیم کنیم! سیستم های گسسته سیستم هایی هستند که در آنها سیستمی دارای تعداد قابل شمارش موقعیتِ حالت هست مثل سیستم های کامپیوتری یا هواپیما و … ولی در سیستم های پیوسته رفتار اونها بر اساس یک تابع پیوسته توصیف میشه که میتونیم رفتارهای سیستم و واکنش آن رو در مقابل رفتارهای گوناگون پیش بینی کنیم همچنین موضوع گراف یا سیستم محاسبه و …برای موارد گسسته کاربرد داره و خیلی از موارد طراحی و پیاده سازی رو از این دید عموما به کار میرن.

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

مهم مهم مهم : در اصل ما با ابزار گسسته به سراغ تولید راه حل برای مسائل پیوسته میریم.

و اما بعد بررسی عوامل پیچیدگی بریم ساختار سیستم های پیچیده رو بررسی کنیم و ببنیم سیستم های پیچیده چه ویژگی دارن:

همونطور که میدونید در دنیا سیستم های پیچیده زیادی داریم از اونهایی که به دست بشر ساخته نشده مثل سیستم عصبی بدن یا کلونی مورچه ها و … تا اونهایی به دست انسان ساخته شدن مثل فضاپیما و …. اما استاد اعظم و عزیز دل من جناب آقای Grady Booch که انشاالله همیشه سالم و سلامت باشن ( حتما در آینده مطالب زیادتری رو از ایشون میزارم تا حسابی روحم قرین رحمت بشه😍) اعتقاد دارن با مطالعه سیستم های پیچیده به پنج ویژگی مشترک میرسیم:

1) ساختار سلسله مراتبی:

غالبا در سیستم های پیچیده، پیچیدگی به شکل سلسله مراتبی ظاهر میشه. هر سیستم پیچیده از چندین زیر سیستم مرتبط و هرکدام از اونها دارای چندین زیرسیستم دیگر هست و این روند تا رسیدن به پایین ترین سطح ادامه داره مثال: کامپیوتر خود شامل صفحه نمایش، کیبورد، RAM، CPU و …هست و به طور مثال CPU خودش از  ثبات، ALU و … تشکیل شده ( یادش بخیر! در کاردانش یه درس داشتیم که معلممون این موارد رو خیلی شیک و مجلسی توضیح میداد🙂).

2) انتخاب دلبخواهانه مولفه های اولیه:

مورد بعدی که استاد اعظم اشاره میکنن موضوع دیدگاه طراح هست و اینکه در سیستم چه چیزهایی جزء مولفه ها و انتخاب های اولیه طراحی هست به این صورت که مواردی ممکنه از دید شما مهم باشه که از دید طراح دیگه اولویت نداشته باشه و فقط در سطح یک انتزاع بمونه.

3) جداسازی دغدغه ها:

توی مورد اول اشاره کردم که سیستم های سلسله مراتبی می تونن به بخش هایی تقسیم بشن یعنی به اصطلاح اهل فن آنها Decomposable هستن اما این جداسازی تقریبا قابل انجام هست و این نکته خیلی مهمه که ارتباط هریک از زیرسیستم ها ( مثل BC یا Service یا هر متریک دیگری) قوی تر از ارتباطات درون خود زیرسیستم ها هست (cohesion و coupling و …) و همین حقیقت به ما میگه این ارتباطات و نرخ تغییرات در آنها ما رو به سمت یک خاصیت دیگه ای از پیچیدگی ها می بره با عنوان جداسازی دغدغه ها (در اصول زیادی این نکته رو میبینیم مثل SOLID).

4) الگوی متداول:

در سیستم های سلسله مراتبی می بینیم که عموما از الگوهای متداولی پیروی میکنن مثل سیستم عروقی که در گیاهان و جانواران مشترک هست و در نرم افزار هم نمونه آن بسیار قابل مشاهده هست(این مورد هم در آینده بیشتر توضیح میدم😎)

5) شکل پایدار میانی:

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

 تا اینجا فقط از پیچیدگی ناله کردیم😜😜 اما در پست بعدی راهکارهای مدیریت پیچیدگی رو با هم بررسی میکنیم پس تا اون زمان اگر این پست به دردتون خورد و دوست داشتید خوشحال میشم با کلیک روی تصویر زیر من رو به یه قهوه مهمون کنید تا مغزم حسابی کیف کنه 😍!!!

 

دسته بندی شده در: