فصل 15(معماری)
در ابتدای فصل 15 به این نکته اشاره میشود که معمار نرم افزار یک برنامه نویس است و این تصور که معمار برنامه نویس از کدنویسی عقب نشینی میکند تصور اشتباهی است.
و معماران نرم افزار ممکن است که به اندازه دیگر برنامه نویسان در فرایند توسعه کد مداخله نداشته باشند اما همچنان درگیر برنامه نویسی هستند.
معماری یک نرم افزار شکلی است توسط سازندگان آن برنامه به آن نرم افزار داده میشود که این شکل نرم افزار را به قسمت های مختلف(کامپوننت های مختلف) تقسیم میکند و چیدمان اجزا و راه های ارتباط آن ها با یکدیگر را مشخص میکند.
و هدف معماری نرم افزار آسان کردن فرایند های توسعه ، قابلیت نگهداری و سایر ویژگی های کیفی نرم افزار است و همچنین پشتیبانی از چرخه حیان سیستم یا نرم افزار است و هدف نهایی آن به حداقل رساندن هزینه طول عمر سیستم و به حداکثر رساندن بهره وری آن سیستم و برنامه نویس است.
در ادامه در رابطه با فرایند توسعه نرم افزار بحث میشود که گفته میشود توسعه نرم افزار اگر سخت باشد ، نرم افزار عمر طولانی و سالمی نخواهد داشت بنابراین معماری نرم افزار باید فرایند توسعه نرم افزار را اسان کند.
سپس در رابطه با دیپلویمنت بحث میشود که میگوید یک سیستم نرم افزاری باید قابل استقرار باشد و یکی از اهداف معماری نرم افزار این است که سیستم قابل استقرا باشد. ودر ادامه مثالی زده میشود که میگوید مثلا تیم توسعه نرم افزار ممکن است در طول فرایند توسعه از چند میکرو سرویس استفاده کنند با این تفکر که توسعه سیستم را آسان میکنند اما در انتهای توسعه متوجه میشوند تعداد میکرو سرویس ها بسیار زیاد شده و فرایند دیپلومنت آن ها به مشکل بر میخورد.
هم چنین سیستم نرم افزاری باید قابلیت نگهداری بالایی داشته باشد.
در انتها نیز مثال هایی زده میشود که میگوید معماران خوب و ماهر جزئیات را از مسائل اصلی و مهم تر جداسازی میکنند و سپس مفاهیم اصلی را از جزئیات جدا میکنند تا هیچ اطلاعاتی راجب جزییات موجود نباشد و به هیچ وجه به جزییات وابسته نباشد (مثال هایی که زده شد مانند اینکه در ابتدا تصمیم گیری شود که از چه نوع پایگاه داده ای استفاده شود) و معماران خوب طوری تصمیم گیری میکنند که تا حد امکان تصمیم گیری در مورد جزئیات به تعویق بیفتد.
فصل 16 (استقلال)
همانطور که در فصل قبل بیان شد یک معماری باید 4 خصوصیت زیر را داشته باشد:
1- موارد استفاده و عملکرد سیستم
2- نگهداری سیستم
3- توسعه سیستم
4- استقرار سیستم (deployment)
مورد اول به این نکته اشاره دارد که معماری مورد نظر باید هدف اصلی نرم افزار را پشتیبانی کند و مثالی که زده میشود این است که مثلا اگر سیستم یک برنامه سبد خرید است در نتیجه معماری باید استفاده از سبد خرید را پشتیبانی کند و این به عنوان اولین دغدغه و اولیوت معمار نرم افزار است.
همچنین معماری نقش اساسی ای در پشتیبانی در عملکرد سیستم دارد و مثالی که زده میشود این است که مثلا سیستمی که باید 1000 مشتری در ثانیه را مدیریت کند باید معماری ای داشته باشد که توان عملیاتی و زمان پاسخگویی مناسبی را برای این سیستم مهیا کند.
در رابطه با توسعه سیستم معماری باید طوری باشد که اقدامات مستقل تیم ها در توسعه نرم افزار با یکدیگر تداخل نداشته باشد.
فصل 17 در رابطه با گرفتن تصیمات در طول توسعه پروژه است.
یک معماری خوب معماری ای است که تصمیمات درباره چارچوب ها ، پایگاه داده ها ، سرور ها و موارد مشابه ،
فرعی و قابل تعویق باشد.
و یک معماری خوب اجازه میدهد این تصمیمات در لحظات آخر بدون تاثیر گذاری و وابستگی به تصمیمات دیگر گرفته شوند.
و در ادامه مثال هایی زده میشود که تصمیم گیری های فرعی را به تعویق می اندازد و به این نتیجه میرسد که:
پایگاه داده ابزاری است که قوانین کسب و کار میتوانن دبه طور غیر مستقیم از آن استفاده کنند. قوانین کسب و کار نیازی به دانستن طرحواره، زبانپ کوئری یا هریک از جزئیات دیگر در مورد پایگاه داده ندارند.تمام قوانین تجاری که باید بدانید این است که مجموعه ای از توابع وجود دارد که میتوان از آنها برای واکشی یا ذخیره داده ها استفاده کرد. این به ما اجازه می دهد تا پایگاه داده را درپشت یک رابط قرار دهیم.
همینطور در رابطه با مرز جداسازی رابط گرافیکی از قوانین کسب و کار صحبت میکند چون قوانین کسب و کار در زمان های مختلف و به دلایل مختلف تغییر میکند. و این به اصل SRP از اصول سالید اشاره دارد که به ما میگوید کجا باید مرز های خود را ترسیم کنیم.
در نتیجه برای ترسیم خطوط مرزی در معماری نرم افزار ابتدا باید سیستم را به کامپوننت تقسیم کنیم.
سپس با شناخت اصول سالید و به ویژه اصل وابستگی معکوس پیکان هارا طوری رسم کنیم که از جزییات سطح پایین به انتزاعات سطح بالا اشاره کند.
ساده ترین عبور از مرز ممکن است یک فراخوانی تابع از یک مشتری سطح پایین به یک سرویس سطح بالاتر است. هم وابستگی زمان اجرا و هم وابستگی زمان کامپایل دریک جهت،به سمت مؤلفه سطح بالاتر قرار دارند.
در ادامه راجب مفاهیمی از جمله Entity و use cases و ... صحبت میشود .
موجودیت یک شی در سیستم است که مجموعه کوچکی از قوانین حیاتی را در بر میگیرد. و حاوی داده و توابعی است که قوانین را روی داده ها اعمال میکند و اجرا میکند.
یوزکیس یا لایه ی ارتباطات حاوی قوانینی است که نحوه و زمان استفاده از قوانین تجاری حیاتی در موجودیت ها را مشخص می کند.
معماری های خوب بر روی یوزکیس ها متمرکزشده اند تا معماران بتوانند با خیال راحت ساختارهایی را که از این موارد استفاده پشتیبانی میکنند بدون تعهد به چارچوب ها، ابزار ها و محیط هاتوصیف کنند.
در ادامه مثالی از معماری یک خانه زده میشود که اولین چیزیکه مهم است این است که مطمعن شود خانه قابل استفاده باشد و اینکه خانه از اجر ساخته شده است یا مصالح دیگر را بعدا میتوان راجبش تصمیم گیری کرد و اطمینان حاصل کرد.
یک معماری نرم افزار خوب اجازه میدهد تا تصمیم گیری در مورد چارچوب ها،پایگاه های داده،سرور های وب و سایر مسائل و ابزار های محیطی به تعویق بیفتد . چارچوب ها گزینه هایی هستند که باید باز گذاشته شوند.یک معماری خوب تصمیم گیری در مورد ،Railsیا ،Springیا ،Hibernateیا ،Tomcatیا MySQL را تا مدت ها بعد در پروژه غیر ضروری می کند. یک معماری خوب تغییر عقیده خود را در مورد آن تصمیمات نیز آسان می کند.یک معماری خوب بر موارد استفاده تاکید می کند و آنها را از نگرانی های پیرامونی جدا می کند.
*در خلاصه های بالا منظور از واژه چارچوب ترجمه تحت الفظی کلمه (فریم وورک) است.
معماری screaming
اصطلاح «معماری فریاد (screaming) » زمانی استفاده میشود که بتوانیم، فقط با نگاه کردن به یک پروژه جدید در یک نگاه، به ایده اصلی درباره اینکه پروژه چه کاری انجام میدهد و در مورد آن چیست، استفاده میکنیم.
همچنین یک الگوی طراحی است که بر اساس اصل جلب توجه به ویژگیهای اساسی و اصلی سیستم تمرکز دارد. در این الگو، ویژگیها و قابلیتهای اصلی سیستم به عنوان هستههای اصلی طراحی معماری در نظر گرفته میشوند. در واقع، معماری فریاد به معنای این است که ویژگیهای اساسی و مهم سیستم در سطح بالا به شکل واضح تعریف شده و مورد بررسی قرار گرفتهاند.
در این الگو، معماران نرمافزار به جای آن که درگیر جزئیات فنی و پیادهسازیهای کوچک شوند، بیشتر به تمرکز بر ویژگیها و نیازهای کاربران میپردازند. این نگرش به طراحی نرمافزار باعث میشود تا سیستم همواره به راحتی توسعه یابی، نگهداری شود و نسبت به تغییرات نیاز حساسیت کمتری داشته باشد.
معماری تمیز (Clean Architecture) یک الگوی معماری است که این الگو به هدف جداسازی اجزای مختلف یک نرمافزار از یکدیگر و ایجاد ساختاری که انعطافپذیر، تستپذیر و قابل نگهداری باشد، میپردازد.
در معماری تمیز، ساختار نرمافزار به لایههای مختلف تقسیم میشود، هر کدام با مسئولیتها و وظایف خاص خود. این لایهها به شرح زیر هستند:
1. لایه ارتباطات خارجی (Entities): این لایه وظیفه نگهداری از موجودیت ها و اشیا اصلی سیستم را دارد، معمولاً به عنوان مدلهای داده نیز شناخته میشوند.
2. لایه ارتباطات (Use Cases) : در این لایه، قوانین کسب و کار و موارد مصرف نرمافزار تعریف میشوند. اینجا مکان انجام عملیات و کنترل فرآیندها و کارهای مربوط به کسب و کار است.
3. لایه رابط کاربری (Interface Adapters): این لایه مسئولیت تبدیل دادهها و فرمتهای مورد استفاده در لایههای دیگر را دارد. این شامل واسطهای کاربری مانند وب سرویسها، رابطهای کاربری گرافیکی، ورودی و خروجی دادهها میشود.
4. لایه ابزارهای خارجی (Frameworks and Drivers): در این لایه، ارتباط با عناصر خارجی نرمافزار مانند دیتابیس، وب سرویسها، و سایر فریمورکها انجام میشود.
یکی از اصول اساسی معماری تمیز این است که لایههای داخلی نباید از لایههای خارجی بیاطلاع باشند. به این معنا که تغییرات در لایههای خارجی نباید به لایههای داخلی تأثیر بگذارد. این الگو باعث میشود که نرمافزار قابل تست، قابلیت نگهداری و اصولاً قابلیت توسعه داشته باشد.
معماری تمیز به توسعهدهندگان اجازه میدهد که بدون نگرانی از تغییرات در لایههای بیرونی، به بهروزرسانی و تغییرات در لایههای داخلی بپردازند، که این امر برای توسعه نرمافزارهای بزرگ و پیچیده بسیار ارزشمند است.
و همانطور که در نمودار صفحه 203 کتاب ترسیم شده است وابستگی به سمت داخل است و با حرکت به سمت داخل انتزاع افزایش می یابد و جزئیات سطح بالاتر را در بر میگیرد.
درونی ترین دایره، عمومی ترین و بالاترین سطح است.
مرزها (boundaries) به عناصر و اجزایی اشاره دارند که نرمافزار ما با بیرون ارتباط برقرار میکند، مثل پایگاهدادهها، وبسرویسها، کتابخانههای خارجی و غیره. مفهوم مرزها به تقسیم بین قسمتهای مرتبط با داخل سیستم و قسمتهایی که به خارج از سیستم ارتباط دارند، اشاره دارد. این تقسیم برای مدیریت پیچیدگی و انعطافپذیری نرمافزار بسیار حائز اهمیت است.
نگهداری مرزها به معنی ایجاد یک واسط مشخص و قابل اعتماد بین داخل و خارج سیستم است. وقتی که مرزها به درستی نگهداری شوند، این امکان وجود دارد که بخشهای مختلف نرمافزار مستقل از یکدیگر توسعه یابند و تغییر کنند. این الگو به توسعهدهندگان امکان میدهد که قسمتهای داخلی سیستم را بدون تغییر و تحت فشار از متغیرهای خارجی انعطافپذیر نگه دارند.
نگهداری درست از مرزها به توسعهدهندگان اجازه میدهد که از تغییرات در خارج از سیستم بدون تأثیرات ناخواسته بر داخل سیستم استفاده کنند. این امر به آنها این اطمینان را میدهد که وقتی تغییراتی در مرزها ایجاد میشود، تنها قسمتهای مربوطه باید تغییر کنند و سایر بخشها درست کار خود را ادامه میدهند. این اصل از اهمیت بسزایی برخوردار است زیرا از پیچیدگی نرمافزار کاسته و کد را قابل فهمتر و قابل نگهداریتر میکند.
مفهوم لایهها و مرزها از اهمیت ویژهای برخوردار است. لایهها و مرزها دو الگوی معماری هستند که به ترتیب برای مدیریت ساختار داخلی سیستم و برقراری ارتباطات با بیرون استفاده میشوند.
1. لایهها (Layers):
لایهها در معماری نرمافزار به تقسیم مؤلفهها و بخشهای مختلف سیستم به لایههای مجزا اشاره دارند. هر لایه وظیفهها و مسئولیتهای خاص خود را دارد و با توجه به این مسئولیتها تقسیم میشود. به عبارت دیگر، هر لایه کارهای خاصی انجام میدهد و نحوه ارتباط با لایههای دیگر مشخص شده است. این تقسیمبندی به توسعهدهندگان امکان میدهد که به طور مجزا و بهینهتر روی اجزای سیستم کار کنند.
2. مرزها (Boundaries):
مرزها به نقاط ارتباطی سیستم با عناصر خارجی مانند پایگاهدادهها، سرویسهای وب، کتابخانههای خارجی و غیره اشاره دارند. مرزها نشاندهنده جدا بودن دنیای خارجی از سیستم ما هستند. نگهداری از این مرزها به معنای داشتن واسطهای مناسب و استاندارد برای ارتباط با این عناصر خارجی است. این کار از یک سو امکان تغییرات در عناصر خارجی را بدون تغییر در داخلی سیستم میسر میکند و از سوی دیگر، کد سیستم را از پیچیدگیهای عمده وابسته به عناصر خارجی محافظت میکند.
در کل، استفاده همزمان از لایهها و مرزها در معماری نرمافزار امکان میدهد تا ساختار داخلی سیستم بهینهتر و مدیریتپذیرتر باشد و همچنین ارتباط با عناصر خارجی بدون ایجاد پیچیدگیهای غیر ضروری امکانپذیر باشد.