معماری نرم افزار چیست و معمار نرم افزار کیست؟
بگذارید با یک حقیقت تلخ و عریان شروع کنیم که کمتر کسی در جلسات شیک استارتاپی یا رویدادهای فناوری درباره آن صحبت می کند: بیش از ۷۰ درصد از پروژه های نرم افزاری بزرگ و استارتاپ های رو به رشد، نه به خاطر کمبود بودجه شکست می خورند و نه به خاطر نداشتن ایده خوب؛ آن ها به خاطر «سکته مغزی کدهایشان» می میرند!
در شروع کار، همه چیز شبیه به یک ماه عسل رویایی است. مدیرعامل ایده ای دارد، چند برنامه نویس پرانرژی استخدام می شوند و با سرعت نور ویژگی های جدید (Features) را به سیستم اضافه می کنند. سایت بالا می آید، اولین کاربران ثبت نام می کنند و همه خوشحالند. اما این خوشحالی یک بازه انقضای بسیار کوتاه دارد. درست در زمانی که کسب وکار جان می گیرد و ترافیک کاربران ده برابر می شود، کابوس از پشت دیوارهای کد بیرون می خزد.
اضافه کردن یک دکمه ساده به سایت که قبلا دو ساعت زمان می برد، حالا دو هفته طول می کشد. سیستم با هر تغییر کوچک، از یک جای دیگر ارورهای عجیب و غریب می دهد. پایگاه داده قفل می کند، سرعت لود صفحات به شدت افت می کند و تیم فنی به جای توسعه محصول، ۲۴ ساعته در حال «آتش نشانی» و رفع باگ های تکراری است. مدیرعامل فریاد می زند: «چرا با وجود اینکه تیم فنی را بزرگ تر کردیم، سرعت خروجی ما نزدیک به صفر شده است؟» و تیم فنی خسته و فرسوده پاسخ می دهد: «کدها گره خورده اند، باید سیستم را از اول بنویسیم!»
این وضعیت، توصیف دقیق پدیده ای به نام مرگ ناشی از بدهی فنی (Technical Debt) است. کدهایی که باری به هر جهت و بدون نقشه راه روی هم انباشته شده اند، حالا کسب وکار را گروگان گرفته اند. مقصر این فاجعه نه برنامه نویسان هستند و نه مدیران؛ مقصر، غیبت رهبری به نام «معمار نرم افزار» است. در این مقاله جامع، قرار است کالبدشکافی کنیم که معماری نرم افزار چیست، چرا بدون آن، سامانه های نرم افزاری محکوم به شکست هستند، و چه کسی وظیفه نجات سیستم های بزرگ را بر عهده دارد.
معماری نرم افزار دقیقا چیست؟
برای درک معماری نرم افزار، باید مرز باریک اما حیاتی میان «کدنویسی» (Coding)، «طراحی نرم افزار» (Software Design) و «معماری نرم افزار» (Software Architecture) را بدانیم. این سه مفهوم معمولا به اشتباه به جای یکدیگر به کار می روند.
کدنویسی، عمل نوشتن خطوط کد برای حل یک مسئله کوچک است (مثل نوشتن یک تابع برای محاسبه تخفیف سبد خرید). طراحی نرم افزار، مربوط به ساختار داخلی کلاس ها و توابع در یک لایه خاص است (مثلا استفاده از اصول SOLID برای اینکه یک کلاس خواناتر و قابل تست تر باشد). اما معماری نرم افزار، نگاه از فرسنگ ها بالاتر به کل سیستم است.
اگر یک نرم افزار را به یک کشور تشبیه کنیم، برنامه نویسان کارگرانی هستند که خانه ها را می سازند، طراحان نرم افزار مهندسانی هستند که نقشه داخلی هر خانه را طراحی می کنند، اما معمار نرم افزار، شهرسازی است که تصمیم می گیرد اتوبان ها کجای شهر باشند، سیستم فاضلاب چطور کار کند، مناطق مسکونی چطور از مناطق صنعتی جدا شوند و شبکه توزیع برق چگونه پایداری کل شهر را در زمان اوج مصرف تضمین کند.
تعریف معماری نرم افزار:
معماری نرم افزار مجموعه کارهای آگاهانه و تصمیمات استراتژیکی است که روی ساختار کلان سیستم، اجزای اصلی آن، نحوه تعامل این اجزا با یکدیگر و با دنیای بیرون اتخاذ می شود. تصمیمات معماری، آن دسته از انتخاب هایی هستند که تغییر دادن آن ها در آینده به شدت هزینه بر، زمان بر و گاهی غیرممکن است. انتخاب نوع پایگاه داده، مدل ارتباطی سرورها، و استراتژی امنیت سیستم، همگی زیر چتر معماری قرار می گیرند.
انواع معماری نرم افزار
برای ساخت یک سیستم پایدار، الگوهای متعددی وجود دارند. یک معمار بر اساس نیاز بیزینس، بودجه و مقیاس پروژه، یک یا ترکیبی از این معماری ها را انتخاب می کند. در ادامه، رایج ترین و قدرتمندترین سبک های معماری را با هم بررسی می کنیم:
۱. معماری یکپارچه (Monolithic Architecture)
در معماری مونولیت یا یکپارچه، کل سیستم از رابط کاربری و منطق کسب وکار گرفته تا لایه دسترسی به پایگاه داده، همگی در قالب یک پروژه واحد و یکپارچه کدنویسی، کامپایل و مستقر (Deploy) می شوند. این سبک سنتی ترین روش توسعه نرم افزار است.
- مزایا و معایب: بزرگ ترین مزیت مونولیت، سادگی اولیه آن است؛ توسعه، تست و استقرار پروژه در روزهای اول بسیار سریع پیش می رود و ارتباط بین بخش های مختلف بدون پیچیدگی شبکه انجام می شود. اما نقطه ضعف بزرگ آن زمانی آشکار می شود که سیستم بزرگ شود. در یک سیستم مونولیت بزرگ، تغییر در یک بخش کوچک ممکن است کل سیستم را از کار بیندازد. همچنین، مقیاس پذیری (Scaling) آن سخت است؛ اگر فقط بخش پردازش تصاویر نیاز به منابع سخت افزاری بیشتری داشته باشد، شما مجبورید کل پروژه یکپارچه را روی یک سرور قوی تر منتقل کنید که این یعنی اتلاف شدید منابع و هزینه.
برای مطالعه بیشتر در باره ی معماری مونولیت میتوانید مقاله معماری مونولیت را مطالعه فرمایید.
۲. معماری میکروسرویس (Microservices Architecture)
معماری میکروسرویس ، نقطه مقابل مونولیت است. در این سبک، سیستم به مجموعه ای از سرویس های کوچک، مستقل و خودمختار تقسیم می شود که هرکدام وظیفه یک لایه از بیزینس را بر عهده دارند (مثلا سرویس پرداخت، سرویس کاربران، سرویس انبار). این سرویس ها هیچ وابستگی مستقیمی به هم ندارند و از طریق پروتکل های شبکه (مثل HTTP API یا پیام رسان هایی مثل RabbitMQ) با هم گفتگو می کنند.
- مزایا و معایب: هر میکروسرویس می تواند پایگاه داده اختصاصی خود، زبان برنامه نویسی متفاوت و تیم توسعه مجزا داشته باشد. اگر سرویس پرداخت خراب شود، کل سایت از کار نمی افتد و کاربر همچنان می تواند محصولات را تماشا کند. همچنین مقیاس پذیری فوق العاده ای دارد. اما عیب بزرگ آن، پیچیدگی سرسام آور در مدیریت شبکه، هماهنگی داده ها (Data Consistency)، مانیتورینگ ارورها و هزینه های بالای نگهداری زیرساخت و سرورهاست. این معماری هرگز برای پروژه های کوچک و نوپا توصیه نمی شود.
برای مطالعه بیشتر در باره ی معماری میکرو سرویس میتوانید مقاله معماری میکرو سرویس را مطالعه فرمایید.
۳. معماری تمیز (Onion / Clean Architecture)
این معماری که توسط عمو باب (Robert C. Martin) محبوب شد، تمرکز خود را روی جداسازی دغدغه ها (Separation of Concerns) و مستقل کردن منطق اصلی کسب وکار (Core Business) از ابزارهای بیرونی مثل پایگاه داده، فریم ورک ها و رابط کاربری می گذارد. ساختار این معماری شبیه لایه های یک پیاز است که هسته اصلی آن شامل قوانین بنیادی بیزینس (Entities و Use Cases) است و لایه های بیرونی شامل دیتابیس و وب سایت هستند. وابستگی ها همیشه از لایه های بیرونی به سمت داخل است.
- مزایا و معایب: بزرگ ترین قدرت Clean Architecture، قابلیت تست پذیری فوق العاده بالا و انعطاف پذیری تغییرات است. اگر بعد از دو سال تصمیم بگیرید پایگاه داده خود را از SQL Server به MongoDB تغییر دهید یا فریم ورک وب خود را عوض کنید، لایه مرکزی و قوانین اصلی بیزینس شما دست نخورده باقی می مانند و نیازی به بازنویسی کل سیستم نیست. عیب آن، پیچیدگی ساختاری در شروع کار، افزایش تعداد فایل ها و کدهای تکراری (Boilerplate Code) است که توسعه اولیه را برای تیم های کوچک کمی کند می کند.
برای مطالعه بیشتر در باره ی معماری تمیز میتوانید مقاله معماری تمیز را مطالعه فرمایید.
۴. معماری رویدادمحور (Event-Driven Architecture)
در معماری رویدادمحور، جریان کار سیستم توسط «رویدادها» (Events) هدایت می شود. رویداد یعنی یک اتفاق مهم که در سیستم رخ داده است (مثلا: "کاربر خرید خود را نهایی کرد"). در این معماری، بخش های مختلف سیستم به صورت تولیدکننده رویداد (Publisher) و مصرف کننده رویداد (Subscriber) عمل می کنند و مستقیما با یکدیگر صحبت نمی کنند، بلکه پیام ها را در یک واسط یا صف پیام (مثل Kafka یا RabbitMQ) می اندازند.
- مزایا و معایب: این سبک بالاترین میزان عدم وابستگی (Loose Coupling) را ایجاد می کند. سیستم به شدت انعطاف پذیر می شود؛ چرا که می توانید بدون دست زدن به کدهای قبلی، یک سرویس جدید اضافه کنید که به رویداد خرید گوش دهد و کارهای جدیدی (مثل صدور فاکتور یا ارسال پیامک هدیه) انجام دهد. از معایب آن می توان به دشوار بودن پیگیری مسیر اجرای یک فرآیند (Debugging)، چالش ناهماهنگی موقت داده ها (Eventual Consistency) و پیچیدگی بسیار بالا در هندل کردن خطاهای زنجیره ای اشاره کرد.
۵. معماری لایه ای (Layered / N-Tier Architecture)
این معماری یکی از رایج ترین و سنتی ترین الگوهاست که کدهای سیستم را بر اساس وظایف فنی به لایه های افقی مجزا تقسیم می کند. معمولا این سیستم شامل ۴ لایه اصلی است: لایه نمایش (Presentation)، لایه منطق بیزینس (Business Logic)، لایه دسترسی به داده (Data Access) و لایه خود دیتابیس. هر لایه فقط مجاز است با لایه مستقیما زیرین خود ارتباط برقرار کند.
- مزایا و معایب: ساختار بسیار ساده، فهم آسان برای همه سطوح برنامه نویسان و سازمان دهی تمیز کدها از مزایای اصلی آن است. تغییر در لایه دیتابیس تا زمانی که اینترفیس آن تغییر نکند، آسیبی به لایه نمایش نمی زند. اما عیب بزرگ آن، ایجاد وابستگی شدید لایه های بالایی به لایه های پایینی است. همچنین برای سیستم های بسیار بزرگ، این ساختار صلب و صلب تر می شود و نمی تواند انعطاف پذیری لازم برای تغییرات سریع یا تکنولوژی های ترکیبی را فراهم کند.
۶. معماری تفکیک مسئولیت دستور و پرس وجو (CQRS)
الگوی CQRS (Command Query Responsibility Segregation) یک سبک معماری پیشرفته است که مسیر خواندن داده ها (Queries) را کاملا از مسیر نوشتن و تغییر داده ها (Commands) جدا می کند. در سیستم های سنتی، ما از یک مدل و یک پایگاه داده برای هر دو کار استفاده می کنیم. اما در CQRS، معمار سیستم را طوری طراحی می کند که عملیات درج و آپدیت روی یک دیتابیس بهینه برای نوشتن انجام شود و عملیات گزارش گیری و خواندن از روی یک دیتابیس بهینه برای خواندن (مثل ایندکس های Columnstore یا دیتابیس های گراف و NoSQL) صورت گیرد.
- مزایا و معایب: این معماری کارایی و سرعت سیستم های با ترافیک بالا را به شدت دگرگون می کند. سرعت خواندن گزارش های سنگین بدون قفل کردن فرآیند خرید کاربران بالا می رود. اما پیاده سازی آن به شدت پیچیده است؛ چرا که معمار باید مکانیزمی طراحی کند تا داده های تغییر یافته در دیتابیس نوشتن، به سرعت و بدون خطا به دیتابیس خواندن منتقل و همگام سازی شوند (Sync Data).
رای مطالعه بیشتر در باره ی معماری تمیز میتوانید مقاله CQRS را مطالعه فرمایید.
معمار نرم افزار کیست و در طول روز دقیقا چه می کند؟
اگر معماری نرم افزار نقشه شهرسازی پلتفرم شماست، معمار نرم افزار (Software Architect) همان مغز متفکری است که این نقشه را ترسیم، هدایت و محافظت می کند. یک تصور غلط و بسیار رایج در شرکت ها وجود دارد: «معمار نرم افزار کسی است که دیگر کد نمی زند، صندلی اش راحت تر است و کارش صرفا کشیدن باکس ها و فلش های رنگی روی تخته وایت برد است!»
این یک فانتزی خطرناک است. معمار نرم افزار، فیلتر و مترجم میان «اهداف تجاری کسب وکار (Business Goals)» و «محدودیت های فنی سیستم (Technical Constraints)» است. او کسی است که بر لبه تیز تکنولوژی حرکت می کند، شکست های پروژه های بزرگ را چشیده، بهای سنگین انتخاب های اشتباه را می داند و حالا از بالا به کل اکوسیستم نگاه می کند.
وظایف اصلی یک معمار نرم افزار را می توان در ۵ محور عملیاتی و روزمره خلاصه کرد:
ادامه مقاله در
https://imaninova.ir/ArticleView?software-architecture-and-architect-role