چرا این دو مفهوم یکی نیستند؟
در دنیای توسعه نرمافزار، مفاهیمی وجود دارند که آن قدر در کنار هم به کار میروند که بسیاری تصور میکنند معنایی یکسان دارند. یکی از شایعترین این سوء تفاهمها، برابر دانستن دو اصطلاح System Design و Software Architecture است. این دو نه تنها متفاوت اند، بلکه نقشهای بنیادین و مکملی در ساخت سیستمهای نرمافزاری پایدار، مقیاسپذیر و قابل نگهداری دارند.
در این مقاله، تفاوت این دو مفهوم را با نگاهی مهندسی و البته دور از پیچیدگیهای غیرضروری توضیح میدهم تا دید دقیقتری نسبت به مراحل طراحی و معماری سیستم بهدست آید. البته این رو هم بگم که موضوعاتی رو که در این مقاله آوردم، بیشتر به درد معماران سیستم و تحلیل گران نرم افزار و مهندسانی که کار سیستم دیزاین میکنند و یا کسانی که میخواهند درک درستی از معماری نرم افزار و سیستم دیزاین داشته باشند، خواهد خورد.

Software Architecture چیست؟
معماری نرم افزار ساختار لایه بندی یک سیستم نرم افزاری را توصیف میکند؛ یعنی تعیین این که:
سیستم از چه لایه هایی تشکیل شده است؟
هر لایه چه مسئولیتی دارد؟
ارتباط لایه ها با یکدیگر چگونه است؟
چه اصول، محدودیت ها و استاندارد هایی باید در کل نرم افزار و لایه ها رعایت شوند؟
تصمیمات کلان در مورد وابستگی ها، سبک معماری داخلی و الگوهای ساختاری چیست؟
در واقع معماری نرم افزار پاسخی است به این سؤال که:
«بخش های مختلف این نرم افزار چگونه باید باهم ارتباط داشته باشند؟»
معمار نرمافزار سه موضوع مهم رو باید در نظر داشته باشه:
معماری خارجی (سطح بیرونی) نرم افزار
در این بخش از معماری، معمار تصمیم میگیرد که نرم افزار رو میخواد به صورت monolith بچیند یا به صورت microservice. طبیعتا معمار ما باید به اصول حاکم بر این دو موضوع و زیرعناوین مهمی که دارند، آشنایی کامل داشته باشه. در برخی موارد معمار حتی تصمیم میگیره نرم افزار رو modular monolithic بچینه تا هزینه ها رو بیاره پایین و در آینده سیستم رو تبدیل کنه به میکروسرویس.
معماری داخلی (سطح داخلی) نرم افزار
در این بخش از معماری، معمار تصمیم میگیره تا لایه های داخلی هر بخش/سرویس/ماژول رو بچینه. این ساز و کار نیازمند این هست که معمار تصمیم بگیره که آیا میخواد از معماری clean استفاده کنه یا از onion یا از hexagonal یا معماری های دیگه. بر اساس نیاز سیستم بررسی میکنه که آیا ddd لازم هست در این پروژه یا خیر. آیا باید از دیزاین پترن های خاصی استفاده کنه یا نه. cqrs لازم هست یا خیر. event source لازم هست یا خیر و از این دست موضوعات. خب اینجا هم طبیعتا معمار ما باید به این موضوعات اشراف داشته باشه تا بتونه تصمیم درست رو بگیره.
استک تکنولوژی
اینکه از چه ابزار های اساسی و زبان های برنامه نویسی باید در این نرم افزار و سیستم استفاده بشه. طبیعتا باید معمار ما این استک رو بر اساس نیازمندی های نرم افزار انتخاب بکند.
System Design چیست؟
طراحی سیستم ساختار و چنیش کامپوننت های گوناگون یک سیستم را توصیف میکند؛ یعنی تعیین این که:
سیستم از چه کامپوننت هایی تشکیل شده است؟
این کامپوننت ها بر چه اساس و اصولی با هم ارتباط میگیرند؟
چه سخت افزار هایی لازم هست؟
چه third-party هایی لازم هست؟
سیستم های persistence، caching، messaging و ... در کجا ها قرار میگیره
و از این دست کار ها ...
چرا این دو به اشتباه یکسان فرض میشوند؟
چند دلیل رایج وجود دارد:
در مصاحبههای فنی، System Design گاهی شامل Architecture هم میشود
بهخصوص در شرکتهای Big Tech که شرکتکننده باید هم معماری و هم طراحی را ارائه دهد. حتما در یک مقاله در مورد مصاحبه ها و تجربه هایی که داشتم، صحبت خواهم کرد. من در هر دو سمت تجربه دارم هم مصاحبه گر بودم و هم مصاحبه شونده. یعنی هر دو سمت رو به خوبی میشناسم و اشتراک تجربه به بچه های تازه وارد و نسل جدید خیلی میتونه کمک کننده باشه و دید بهتر و بازتری بده.
پوشش مفهومی بالایی دارند
بسیاری از تصمیمهای design بدون در نظر گرفتن architecture معنی ندارند. این توازن و تفکیک مفاهیم رو باید به درستی انجام داد.
در تیمهای کوچک مرزها عملاً ناپدید میشود
یک نفر هم طراح سیستم است و هم معمار نرم افزار و حتی شاید کار های دیگری هم داره انجام میده پس در نتیجه تمرکز لازم رو نخواهد داشت.
اینها دلایلی هستند که این دو مفهوم بعضاً یکسان در نظر گرفته میشه.
فرض کنید معماری شما monolith است اما قصد دارید سیستم را به میلیون ها کاربر سرویس دهید.
هرچقدر هم طراحی ویژگیها را خوب انجام دهید، زیرساخت تحمل این حجم را نخواهد داشت.
معماری اشتباه سیستم را محدود میکند. برعکس، معماری خوب میتواند با طراحی متوسط هم کار کند.
زیرا ستونهای اصلی از ابتدا درست چیده شدهاند. ناگفته نماند که تجربه شخص معمار و تحلیل گر نرم افزار در تصمیم گیری های مهم خیلی تاثیر بالایی داره و آینده سیستم و بیزینسی که روی اون سیستم میاد بالا رو جهت بده. من همیشه پیشنهاد میدم به مهندسان نرم افزار و معمار هایی که نمیتونن تصمیم بگیرن و R&D ها هم نمیته کمک کننده باشه، حتما با یک شخص با تجربه تر از خودشون مشورت داشته باشند تا خدایی نکرده روی معماری و سیستم دیزاین ریسک بالایی نداشته باشن.
پس یه جمع بندی کلی باهم داشته باشیم؛
Software Architecture تصویری از لایه بندی ها، وابستگی ها و ارتباطات ارائه میدهد.
System Design تصویری کلان، استراتژیک و بلند مدت از ساختار اصلی و کاپوننت های سیستم ارائه میدهد.
اگر معماری را اسکلت سیستم بدانیم، طراحی سیستم جزئیات اجرایی آن اسکلت است.
هیچ کدام جای دیگری را نمیگیرند و هر دو برای ساخت یک محصول حرفهای و مقیاسپذیر، ضروری هستند.
برای درک بهتر و تکمیلی تر یه مثال واقعی بزنم که دیگه جا بیوفته و موضوع رو تموم کنیم:
اینکه توی یک نرم افزار clean داشته باشیم یا onion، با ddd بزنیم یا بدون اون، event driven باشه یا نه، cqrs داشته باشیم یا نه و ... دیزاین پترن ها و موضوعات پیرامونی اون ها همشون در بحث معماری نرم افزار (معماری داخلی) بحث میشن ولی اینکه reverse proxy هامون، gateway هامون، سرویس های خارجی متمرکزمون مثل SSO ها یا CAS برای احراز هویت هامون یک اینکه Elastic رو کجا بزارم، Message Broker هام رو کجا بزارم، دیتابیس هامون رو کجا بزاریم، WAF رو کجا بزارم تو زیرساختم، ردیس کش ها رو کجا بزارم، این ها چطوری باهم حرف بزنن و ... اینها همشون در بحث سیستم دیزاین صورت میگیره.
یه شرکت درست حسابی باید مسئولین فنی دپارتمان ها رو طوری تربیت کنه و شرح وظایف بده که افرادی همانند معمار و تحلیل گر نرم افزار بتونه تمام SRS های خودش رو با استاندارد های IEEE مطابقت بده و در چهارچوب اون حرکت کنه. بستر باید فراهم بشه برای چنین کاری والا مستند سازی این همه اسناد در واحد های DCC کار هر کسی نیست. باید یک هماهنگی و هارمونی درستی داشته باشند با دیگر واحد های کاری.
امیدوارم کمک کننده بوده باشه.