وقتی یک خانه ساخته میشود، نقشههای مختلفی از ساختمان تهیه میشوند که هر کدام از این نقشهها برای مخاطبان خاصی هستند و از زاویههای مختلفی به ساختمان نگاه میکنند. اطلاعات مختلفی در هر کدام از این نقشهها نهفته شده است و هیچکدام از آنها به تنهایی ساختمان را توصیف نمیکنند. از جمله این نقشهها مثلا نقشهی لولهکشی ساختمان، برقکشی ساختمان، طراحی فضاهای ساختمان و ... میباشد. هر کدام از این موارد در جای خود مفید خواهند بود و بدون وجود آنها، قطعا در زمان نیاز دچار مشکل خواهیم شد.
اگر چه که یک ساختمان دارای نقشههای مختلفی میباشد که از زاویههای مختلف به آن نگاه میکنند، اما هر نقشه خود دارای جزییاتی است که سطح این جزییات نیز خود مسئلهی مهمی است. به عنوان مثال وقتی ما به بنگاه املاک مراجعه میکنیم، به صورت کلی مشخصات ساختمان را میگوییم مثل آپارتمانی یا همکف، تعداد طبقه، تعداد اتاقها و .... در صورتی که نقشهی طراحی یک ساختمان وقتی مشاهده میشود جزییات فراوانی از جمله وضعیت شیشهها، اندازهی دیوارها، جهت بازشدن درها و ... را مشاهده میکنیم. قطعا وجود این جزییات برای مخاطبان خاص آن مهم است مثل مهندس ساختمان. اما برای افرادی نیز این حد جزییات لازم نیست و بیشتر به دنبال طرح کلی ساختمان هستند.
مثالی که سایمون برای میزان جزییات یک طرح بیان میکند، نقشه است! احتمالا زمانهایی بوده که ما نیاز به نقشه داشتهایم. گاهی در این نقشهها به دنبال آن بودهایم که دقیقا موقعیت خیابانها، کوچهها و مکانهای مهم را مشاهده کنیم. گاهی نیز به دنبال آن بودهایم که کلیهی مکانهای مهم یک شهر یا استان را مشاهده کنیم. گاهی نیز به دنبال تعیین مسیری برای سفر از یک شهر به شهر دیگر بودهایم و در مقیاس کشور به نقشه نگاه کردهایم. گاهی نیز به دنبال کشورها و موقعیتهای آن در جهان بوده و به نقشهی کرهی زمین نگاه کردهایم. تمامی این کارها را به سادگی با کوچکنمایی یا بزرگنمایی نقشه انجام میشوند و در هر زمان متناسب با نیاز، از میزان بزرگنمایی مناسب استفاده میشود. آیا ما نمیتوانیم از نقشه ایده بگیریم و طرحهای معماری را نیز به همین شکل طراحی کنیم؟!
احتمالا افراد زیادی هستند که حتی اگر از UML (Unifed Modeling Language) استفاده نکردند، نام آن را شنیده باشند. این روش، زمانی به عنوان یک روش استاندارد برای طراحی و مستندسازی معماری در نظر گرفته میشد اما در طول زمان با روی کار آمدن روشهای چابک و محدودیتهای این روش، کم کم سازمانها به این نتیجه رسیدند که تعدادی «خطوط و جعبه» برای توصیف معماری کافی است! اگر چه واقعا شاید مقداری شکل و شمایل برای توصیف معماری کافی باشد و کنار گذاشتن یکسری استاندارهای دست و پا گیر (مثل UML) برای به دست آوردن چابکی خوب باشد، اما بسیاری از تیمها با استفاده از روشهای جدید از نظر ارتباطی دچار مشکل شدهاند. کافی است که طرح معماری دو تیم مختلف یا سازمان مختلف را جابهجا کنیم و از هر سازمان بخواهیم که معماری سازمان دیگر را توصیف کنند. در این وضعیت به احتمال زیاد مشکل اصلی را مشاهده خواهیم کرد.
اگر اکثر طرحهای کنونی را که برای توصیف معماری استفاده میشوند مشاهده کنیم، معمولا نشانهگذاریهایی را مشاهده میکنیم که بین طرحهای مختلف متفاوت هستند مثل رنگها، شکلها و خطوط مختلف، نامگذاریهای مبهم، روابط بدون نام یا مبهم بین موجودیتها، واژگان عمومی. اگر همین الان به گوگل مراجعه کنید و در مورد نمونه طرح معماری در تصاویر جستجو کنید، حجم زیادی از تصاویر را در رنگها و شکلها مختلف مشاهده میکند که حتی بعد از بررسی آنها، از طریق خود عکس نمیتوانید در یک نگاه معماری را متوجه شوید و احتمالا مجبور میشوید حجم زیادی از توضیحات را بخوانید تا معماری را درک کنید. در کنار این موارد، گاهی ما به دنبال معماری کلی و گاهی معماری با جزییات فراوان هستیم و معمولا این نیز مشکل دیگری در طرحهای کنونی معماری سازمانها میباشد.
مدل C4 بهعنوان روشی برای کمک به تیمهای توسعه برای توصیفکردن و تعامل و صحبت در مورد معماری نرمافزار، هم در جلسات طراحی اولیه و هم هنگام مستندسازی ایجاد شده است. به عبارتی این روش به ما کمک میکند تا برای کد خود نقشههایی را در سطوح مختلف با جزئیات مختلف طراحی کنیم به همان روشی که از چیزی مانند نقشههای گوگل برای بزرگنمایی و کوچکنمایی منطقهای که به آن علاقه داشتیم استفاده میکردیم.
اگرچه هدف اصلی طراحی این مدل، استفادهشدن توسط معماران و توسعهدهندگان نرمافزار است، مدل C4 راهی را برای تیمهای توسعه نرمافزار فراهم میکند تا به طور کارآمد معماری نرمافزار خود را در سطوح مختلف از جزئیات بیان کنند. سطوحی که هر کدام از آنها توضیحات مختلف برای انواع مختلف مخاطب (تیم تست، تیم توسعه، کارفرما و ...) فراهم میکنند. در کنار جزییات مختلفی که هر کدام از این سطوح فراهم میکنند، افراد تیمها میتوانند با زبانی مشترک با یکدیگر تعامل کنند بدون این که درگیر جزییات اضافه شوند.
مدل C4 برخلاف توضیحات و معایبی که برای روشهای قدیمی مثل UML گفتیم، یک روش مبتنی بر «نشانهگذاری» نیست. به عبارتی قرار نیست در این روش برای توصیف هر موجودیت روش خاصی را مشخص کنیم و علایم و نگارشهای مختلفی را به صورت یکسان در همهجا اعمال کنیم. این روش از رویکرد «انتزاع» برای نمودارسازی معماری نرمافزار استفاده میکند. انتزاعهایی که نشان میدهد معماران و توسعهدهندگان نرمافزار چگونه در مورد نرمافزاری که طراحی میکنند، فکر میکنند و یا چگونه آن را میسازند. در واقعیت در این روش، ما مجموعه کوچکی از انتزاعها و انواع نمودارها را داریم که یادگیری و استفاده از مدل C4 را بسیار آسان میکند. دیگر قرار نیست که ما قواعد و نشانهگذاریهای فراوانی را مشخص و تعریف کنیم. البته نکات و کلیتهایی در انتها به عنوان پیشنهاد چگونگی طراحی نمودارها بیان میشود که در حد توصیه هستند برای این که طراحها مفیدتر باشند اما هیچگونه شیوهی رسمکردن خاصی (مثل چگونگی علامتها، خطوط، جعبهها و ...) اجبار نمیشود.
در ادامه خواهیم دید که در مدل C4 ما از چهار نمودار برای مجسمسازی سطوح مختلف معماری استفاده خواهیم کرد. توجه به این نکته نیز مهم است که نیازی به استفاده از هر چهار سطح نمودار نیست. این نمودار تعریف میشوند اما فقط آنهایی که ارزش اضافه میکنند، برای بسیاری از تیمهای توسعه نرمافزار کافی هستند. به عنوان مثال احتمالا نمودارهای System Context و Container (در ادامه آشنا میشویم) برای بسیاری از تیمها کافی هستند. همچنین به احتمال زیاد نمودار Code برای اکثر تیمهای توسعه غیرالزامی هستند و میتوانند از طریق ابزارهای خودکار در این زمینه تولید شوند.
برای ایجاد سطوح مختلفی از کد که در بخش قبلی توضیح داده شدند، ابتدا به مجموعهای از انتزاعهای مشترک نیاز داریم تا همه افراد از این زبانی مشترک برای توصیف ساختار ایستای سامانه نرمافزاری استفاده کنند. مدل C4 ساختارهای ایستا یک سامانه نرمافزاری را از چهار نظر زیر مورد بررسی قرار میدهد:
هر کدام از موارد بالا نمایندهی موارد خاصی هستند که در ادامه هر کدام را توصیف میکنیم اما همانطور که از طریق تصویر مشخص است، به صورت ساختاری هر سامانه نرمافزاری (software system) دارای یک زمینه (context) میباشد و افرادی حقیقی یا غیر حقیقی (person) از آن استفاده میکنند. این سامانه از مجموعهای از ظروف (containers) تشکیل شده است. هر کدام از این ظروف حاوی یک یا چندین مولفه (component) هستند که هر کدام از آنها نیز از مجموعهای از کدها (code) تشکیل شدهاند.
ممکن است مفاهیم بالا را در زمینه و نرمافزارهای دیگر مشاهده کرده باشید اما تعاریف هر کدام از موارد بالا به صورت خاص توسط مدل C4 مشخص شده است. مثلا اکثر افراد با شنیدن «ظرف» احتمالا مفاهیم داکر و ابزارهای مشابه در این زمینه را به یاد میآورند اما مفهوم آن در مدل C4 کاملا متفاوت و خاص آن میباشد. حتی عدهای نیز با شنیدن «مولفه» معادلهایی را برای آن در زبانهای برنامهنویسی مختلف مثل جاوا یا C# به یاد میآورند در حالی که زبانهایی هم هستند که برای این مفاهیم، اسمهای دیگری دارند یا معادلی ندارند. با این حال تعریف «مولفه» کاملا خاص مدل C4 هست و نباید با این موارد اشتباه گرفته شود. به همین دلیل بیش از این که با نمودارهای مربوط به C4 آشنا شویم، ابتدا هر کدام از انتزاعهای بالا را بررسی میکنیم.
یک فرد نمایندهی استفادهکنندگان سامانه میباشد. این فرد میتواند یک فرد حقیقی یا مجموعهای از افراد باشند یا حتی گاهی یک ماشین خودکار باشد که از سامانهی نرمافزاری استفاده میکند.
یک سامانه نرمافزاری یک انتزاع سطح بالا میباشد و توصیفکننده چیزی میباشد که ارزشی را به کاربران خود (خواه انسان باشند یا نباشند)، ارائه میکند. یک سامانه نرمافزاری همیشه به صورت منفرد نیست و احتمال بسیار زیاد در تعامل با سامانههای نرمافزاری دیگری به اهداف خود میرسد. این سامانههای نرمافزاری ممکن است همگی توسط یک تیم توسعه داده شده باشند یا این که توسط تیمهای مختلفی توسعه داده شده باشند.
در مدل C4، یک ظرف نمایندهی یک برنامه یا مخزن ذخیره داده میباشد. در واقعیت ظرف چیزی است که لازم است اجرا شود تا کل سامانه بتواند به درستی عمل کند. اما اگر به خواهیم به صورت جزئیتر آن را بیان کنیم هر چیزی مانند برنامههای سمت سرور یا سمت کلاینت، برنامههای موبایل، برنامههای کنسولی، پایگاههای داده یا یک پوشه یا فایل در فایل سیستم، یک اسکریپ و ... نماینده ظرف میباشد.
یک ظرف در اصل یک جعبهای است که در داخل آن برخی از کدها (به صورت تک برنامه یا مجموعهای از نخهای موازی) اجرا شده یا برخی از دادهها ذخیره میشود. هر ظرف را نیز میتوان به عنوان موجودیت زمان اجرا که به طور جداگانه قابل استقرار یا اجرا است، در نظر گرفت.
مولفه مجموعهای از عملکردهای مرتبط است که در پشت یک رابط تعریفشده قرار میگیرند. به عبارتی مجموعهای از کلاسهای پیادهسازی که به منظور پیادهسازی یک هدف نوشته شدهاند و این هدف را از طریق یک رابطی مثل ارتباط شبکهای یا فایلی یا ... فراهم میکنند، مولفه گفته میشود. جنبههایی مانند نحوه بستهبندی آن مولفهها (مثلا به فرمت JAR یا DLL یا ...) یک بحث جدا است.
نکته مهمی که در اینجا باید به آن توجه کرد این است که همه اجزای داخل یک ظرف معمولا در یک فضای پردازش یکسان اجرا میشوند. در مدل C4، «مولفه»ها به طور جداگانه واحدهای قابل استقرار نیستند. (مثلا مجموعهای از کلاسها که در درون back-end یک سرور قرار گرفته و بحث مدیریت سفارشها را (از میان کلیهی دیگر فرایندهای یک رستوران) انجام میدهد، یک مولفه است چون این بخش به صورت جدا قابل استقرار و اجرا نیست و در هنگام استقرار ظرف back-end اجرا میشود.
اکنون که با انتزاعهای مختلف در مدل C4 آشنا شدیم، در ادامه با ایجاد مجموعهای از نمودارهای مختلف در بحث زمینه (context)، ظرف (container)، مولفه (component) و به صورت اختیاری کد (code) (به عنوان مثال کلاس UML) انجام میشود. نام مدل C4 نیز از همین نمودارها نشات گرفته است.
برای بیان مثال و فهم بهتر مطالب، سامانهای را نیز برای بررسی مشخص میکنیم. سامانهی بانکداری به عنوان نمونه توسط سایمون در هنگام معرفی مدل C4 بیان شده است که توضیحات و نمودارهای آن به صورت کامل میباشند. در ادامه ما نیز از همین سامانه به عنوان نمونه استفاده میکنیم.
نمودار زمینه (context) به عنوان شروع برای مجسمسازی و مستندسازی سامانه نرمافزاری محسوب میشود. این نمودار در واقعیت یک دید کلی از سامانه هدف و تمامی تعاملات آن با سامانههای دیگر (خواه همان تیم توسعه داده باشد یا تیمهای دیگر) ارائه میدهد. بهتر است در رسم این نمودار، سامانهی نرمافزاری هدف به صورت یک جعبه در میان صفحه قرار گرفته و بقیه سامانهها و تعاملاتشان با سامانهی ما در اطراف آن قرار بگیرند. همچنین پیشنهاد میشود که همین ساختار را در هنگام بزرگنمایی و رسم دیگر سطوح مدل C4، حفظ نمایید تا استفاده از نمودارها تسهیل شود.
دقت شود در این نمودار بیان جزییات سامانه، تکنولوژیهای استفاده شده، پروتکل ارتباطی بین سامانهها و ... اهمیت ندارند و در صورت نیاز، باید از دیگر نمودارها استفاده شود. در این نمودار تمرکز تنها باید بر روی افرادهایی باشند که از سامانه استفاده میکنند، سامانههایی که از سامانهی ما دادهای را دریافت یا ارسال میکنند. این نمودار بهترین نمودار برای نشاندادن به افراد غیرفنی میباشد.
بعد از رسمشدن نمودار زمینه و مشخصشدن سامانه و تعاملات آن با دیگر سامانهها، باید سامانه را بزرگنمایی کنیم و تمامی ظروف (containers) آن را رسم کنیم. تعریف مربوط به ظروف را در بخشهای قبلی مشاهده کردیم و در این قسمت از بیان دوباره آن خودداری میکنیم. با نگاه به عکس بالا میتوانید میتوانید مثالهای عملی آن را مشاهده کنید.
نمودار ظرف شکل و ساختار سطح بالای معماری نرمافزار و نحوه توزیع بخشهای مختلف سامانه را به منظور رسیدن به هدف نهایی سامانه نشان میدهد. همچنین تلاش میشود در این نمودار، تکنولوژیهای اصلی انتخابشده برای پیادهسازی بخشهای مختلف و نحوه ارتباط ظروف (استفاده از API، پایگاهداده، صف و ...) با یکدیگر نشان داده شود. این نمودار در عین سادهبودن، با تمرکز بر معماری به صورت سطح بالا است که برای توسعهدهندگان نرمافزار و کارکنان بخش پشتیبانی سامانه مفید است.
نمودار زمینه و ظروف، جزو پرکاربردترین نمودارها هستند که در اکثر سازمانها و تیمها میتواند مفید واقع شود. اکثرا نمودارهای دیگر بسیار کم استفاده میشوند اما این دو نمودار توضیح دادهشده جزو مهمترین نمودارها هستند.
در نمودار مولفهها (components)، هر ظرف را بزرگنمایی میکنیم و بیشتر تجزیه میکنیم تا بخشهای اصلی و تعاملات آنها را شناسایی کنیم. (دقت شود این بخشها همگی در داخل ظرف هستند و به صورت جداگانه قابل اجرا نیستند) معمولا همه چیز به صورت یک جسم متمرکز (monolithic) نیست و بخشهای مختلف در یک سامانه دیده میشود. نمودار کامپوننت نشان میدهد که چگونه یک ظرف از تعدادی «بخشهای معنیدار» تشکیل شده است، هر یک از آن اجزا چیست و فعالیتهای آنها و تکنولوژی آنها چیست.
در نهايت، در نمودار کد برای یک مولفه، ما پیادهسازی آن را تصویر میکنیم. معمولا برای این قسمت از نمودار معروف UML استفاده میشود که این نمودار هم توسط محیطهای توسعهدهندهی فراوانی پشتیبانی میشود و به راحتی از طریق کد، قابل خروجی گرفتن است. به همین دلیل در اکثر موارد نیاز به این نمودار نیست و نمودارهای دیگر کافی هستند. البته اگر چه ابزارهای مختلف توانایی رسم این نمودار را به صورت خلاصه دارند، اما باید در این نمودار تا حد امکان تنها کلاسها و کدهایی را قرار دهیم که داستان اصلی آن مولفه را بیان میکنند. مثلا رسم کلاسهای کاربردی (utility) یا پیادهسازیهای مختلف یک واسط (interface) در اکثر موارد لازم نیست.
همانطور که در ابتدای توضیحات بیان شد، در نمودارهای بالا ما از روش یا قواعد نمایشی خاصی برای رسم نمودارها استفاده نکردیم. این از مزیتهای مدل C4 میباشد. با این حال سازندهی این طرح، تعدادی پیشنهاد برای رسم بهتر نمودارها ارائه میدهد. در پایان، تعدادی از این پیشنهادات را به صورت خلاصه بیان میکنیم:
این مطلب، بخشی از تمرینهای درس معماری نرمافزار در دانشگاه شهیدبهشتی است.