در این نوشته، بهصورت ساده و خلاصه با بیست مفهوم مهم در دنیای نرمافزار آشنا میشویم. هدف این مقاله این نیست که هر موضوع را درسطح عمیق و دانشگاهی بررسی کند، بلکه میخواهد یک دید اولیه و کاربردی نسبت به مفاهیم نام برده شده ارائه دهد؛ به گونه ای که اگر بعدها با نام این مفاهیم برخوردیم بتوانیم بفهمیم درباره چه چیزی صحبت میشود و چه مسئلهای را حل میکند. در این نوشته برای هر موضوع، سعی شده تا توضیحی روان، کوتاه و قابلفهم بیان شود.
مهندسی آشوب یا Chaos Engineering یک رویکرد پیشگیرانه در توسعه نرمافزار است که در آن، مهندسان به صورت عمدی و کنترلشده، اختلالاتی را در سیستم ایجاد میکنند تا میزان مقاومت و تابآوری سامانه را بسنجند.برای مثال تصور کنید که یک سیستم بزرگ دارید که به خوبی کار میکند؛ در مهندسی آشوب، عمداً یک سرور را خاموش میکنند، و ارتباط شبکه را قطع میکنند یا ترافیک ساختگی بسیار بالایی به سیستم میفرستند. در اینجا هدف این نیست که سیستم را خراب کنند، بلکه میخواهند قبل از اینکه یک خرابی واقعی در دنیای واقعی و برای کاربران نهایی رخ دهد، نقاط ضعف سیستم را شناسایی شوند. معروفترین ابزار در این زمینه Chaos Monkey می باشد که توسط شرکت نتفلیکس ساخته شده است. این کار به تیمها این اعتماد را میدهد که سیستمشان در برابر اتفاقات غیرمنتظره به خوبی دوام میآورد یا نه و از تاب آوری سیتم خود در شرایط بحرانی مطمئن باشند.
الگوی Backend for Frontend یا به اختصار BFF زمانی کاربرد پیدا میکند که برنامهی ما چندین رابط کاربری یا اصطلاحا Frontend مختلف داشته باشد؛ مثلاً یک نسخه وب، یک اپلیکیشن موبایل و یک نسخه برای ساعت هوشمند. به جای اینکه همه این کلاینتها به یک بک اند واحد و یکپارچه متصل شوند که باعث پیچیدگی و ارسال دادههای اضافی میشود، برای هر کلاینت یک بکاند اختصاصی میسازیم. در این معماری، تیم توسعهدهنده موبایل بکاند مخصوص خودش را دارد که دقیقاً دادهها را همانطور که اپلیکیشن موبایل نیاز دارد قالب بندی میکند و تیم وب هم بکاند مخصوص خودش را دارد. این کار باعث میشود توسعه رابطهای کاربری مستقل تر، سریع تر و بهینه تر شود و از ایجاد گلوگاه در یک بکاند مشترک جلوگیری گردد.
مفهوم AI4SE یا Artificial Intelligence for Software Engineering به معنای استفاده از ابزارها و تکنیکهای هوش مصنوعی برای بهبود و خودکارسازی فرآیندهای مهندسی نرمافزار است. در واقع، در اینجا هوش مصنوعی به کمک برنامهنویسان و تیمهای توسعه می آید تا کارشان را بهتر انجام دهند. مثال بارز این موضوع، ابزارهایی مانند GitHub Copilot یا ChatGPT است که در نوشتن کد، پیدا کردن باگها، تولید تستهای خودکار و حتی مستندسازی کدها به توسعهدهندگان کمک میکنند. با استفاده از AI4SE، کارهای تکراری و زمان بر به هوش مصنوعی سپرده میشود و برنامهنویسان میتوانند تمرکز خود را روی حل مسائل پیچیده تر، معماری سیستم های نرم افزاری و نوآوری بگذارند. این رویکرد به شدت باعث افزایش بهرهوری و کاهش خطاهای انسانی در چرخه حیات توسعه نرمافزار میشود.
SE4AI یا Software Engineering for Artificial Intelligence به معنای استفاده از اصول، استانداردها و روشهای مهندسی نرمافزار برای ساخت، توسعه و نگهداری سیستمهای مبتنی بر هوش مصنوعی و یادگیری ماشین است. ساخت یک مدل هوش مصنوعی در محیط آزمایشگاهی یک چیز است، اما تبدیل آن به یک محصول نرمافزاری پایدار که در دنیای واقعی و در مقیاس بالا کار کند، چالشهای بزرگی دارد. SE4AI به مهندسان و توسعه دهندگان میآموزد که چگونه کدهای مربوط به مدلهای هوش مصنوعی را تست کنند، چگونه آنها را ورژنبندی کرده و چگونه کیفیت دادهها و مدلها را در طول زمان تضمین کنند. در واقع، این حوزه تلاش میکند تا بی نظمیهای موجود در پروژههای داده محور را با استفاده از نظم مهندسی نرمافزار، مدیریتپذیر و مطمئن کند.
کلمه MLOps ترکیبی از Machine Learning و Operations است و شباهت زیادی به مفهوم DevOps در توسعه نرمافزار سنتی دارد. هدف MLOps ایجاد یک چرخه خودکار و یکپارچه برای توسعه، استقرار و نگهداری مدلهای یادگیری ماشین در محیط عملیاتی است. وقتی دانشمندان داده یک مدل هوش مصنوعی میسازند، انتقال آن به محیط واقعی کسبوکار نیازمند به پایش مداوم است؛ زیرا مدلهای هوش مصنوعی با گذشت زمان و تغییر رفتار دادهها، دقت خود را از دست میدهند. ابزارها و فرآیندهای MLOps کمک میکنند تا مدلها به صورت خودکار آموزش مجدد ببینند، تست شوند و با کمترین میزان دخالت انسانی در سرورها بهروزرسانی گردند. این کار باعث میشود استقرار پروژههای هوش مصنوعی سریعتر، امنتر و با قابلیت اطمینان بسیار بالاتری صورت گیرد.
در گذشته، برای راهاندازی سرورها و شبکهها، مدیران سیستم باید به صورت دستی سیستمعامل نصب میکردند و تنظیمات را انجام میدادند که این کاری زمانبر و پر از خطای انسانی بود. مفهوم IaC یا «زیرساخت به عنوان کد» به ما اجازه میدهد تمام این فرآیندها را با نوشتن کدهای متنی ساده خودکار کنیم. با ابزارهایی مثل Terraform یا Ansible، یک فایل تنظیمات نوشته می شود و با اجرای آن، صدها سرور در عرض چند دقیقه با پیکربندی دقیق و یکسان ساخته میشوند. این کار باعث میشود مدیریت زیرساختها تکرارپذیر، سریعتر و قابل نسخهبندی شود؛ درست مانند کاری که کدهای نرمافزاری انجام می دادند.
در معماری مایکروسرویسها، ما با دهها سرویس کوچک روبرو هستیم. درگاه API یا API Gateway مانند یک درب ورودی اصلی برای کاربران عمل میکند. کاربر تمام درخواستهایش را به این درگاه میفرستد و درگاه آنها را به سرویسهای مربوطه هدایت میکند؛ همچنین کارهایی مثل احراز هویت را در همین بخش انجام میدهد. از طرف دیگر، Service Mesh برای ارتباطات داخلی خود سرویسها با یکدیگر استفاده میشود. وقتی سرویس الف میخواهد با سرویس ب صحبت کند، Service Mesh ترافیک، امنیت و خطایابی بین آنها را مدیریت میکند.به صورت خلاصه، Gateway برای ارتباط با بیرون و Service Mesh برای مدیریت ارتباطات درونتیمی سرویسها می باشد.
الگوی CQRS یا Command Query Responsibility Segregation یک رویکرد معماری است که عملیات خواندن دادهها (Query) را از عملیات نوشتن یا تغییر دادهها (Command) جدا میکند. در سیستمهای سنتی، معمولاً از یک دیتابیس برای خواندن و نوشتن استفاده میشود که در ترافیک بالا به گلوگاه تبدیل میگردد. با استفاده از CQRS، ما میتوانیم یک مدل دیتابیس اختصاصی و بهینه شده برای جستجو و خواندن سریع داشته باشیم و دیتابیس دیگری را صرفاً برای ثبت و ویرایش اطلاعات در نظر بگیریم. این الگو پیچیدگی سیستم را افزایش میدهد، اما مقیاسپذیری و کارایی نرم افزار را در سیستمهای بزرگ و پرترافیک به میزان قابل توجهی بالا میبرد.
در معماری رویداد محور یا EDA ، اجزای مختلف سیستم از طریق تولید و واکنش به «رویدادها» با هم ارتباط برقرار میکنند. یک رویداد میتواند ثبتنام یک کاربر جدید یا پرداخت یک فاکتور باشد. وقتی یک رویداد اتفاق میافتد، یک پیام در سیستم منتشر میشود و هر سرویسی که به آن اتفاق علاقه یا نیاز دارد، آن را دریافت کرده و مسئولیت خودش را انجام میدهد. مزیت بزرگ این معماری این است که سرویسها به شدت از هم مستقل میشوند. اگر سرویس ایمیل قطع شود، سیستم ثبتنام از کار نمیافتد، بلکه ایمیلها در صف میمانند تا سرویس دوباره وصل شود.
برخلاف نامش، در معماری Serverless سرورها همچنان وجود دارند، اما مدیریت، نگهداری و مقیاسدهی آنها کاملاً بر عهده ارائهدهنده خدمات ابری برای مثال آمازون یا گوگل خواهد بود. در این مدل، برنامه نویس فقط کدهای خود را مینویسد و آپلود میکند. سیستم ابری به صورت خودکار هر زمان که درخواستی بیاید، کد را اجرا میکند.قسمت مهم این معماری این است که فقط به اندازه همان چند میلیثانیهای که کد اجرا میشود پول پرداخت میشود و اگر سیستم هیچ کاربری نداشته باشد، هزینهای هم نخواهد داشت. این معماری دغدغههای زیرساختی را برای تیم توسعه به طرز چشمگیری کاهش می دهد.
در رویکرد API-First، قبل از اینکه طراحان رابط کاربری را بسازند یا برنامهنویسان کدهای بکاند را بنویسند، تیمها دور هم جمع میشوند و ابتدا قرارداد و ساختار APIها را طراحی و مستند میکنند. با این کار، API به عنوان یک محصول مستقل و اولویتدار در نظر گرفته میشود. پس از نهایی شدن طراحی API ، تیمهای فرانتاند و بکاند میتوانند به صورت موازی و همزمان کار خود را پیش ببرند؛ زیرا دقیقاً میدانند دادهها با چه فرمتی رد و بدل خواهند شد. این رویکرد سرعت توسعه را بالا برده و از بروز ناهماهنگی بین تیم های مختلف جلوگیری میکند.
طراحی دامنه محور یا DDD یک روش توسعه نرمافزار است که تمرکز اصلی خود را بر روی درک عمیق منطق و قوانین کسبوکار میگذارد. در سیستمهای بسیار پیچیده مثل سیستمهای بانکی یا بیمه، برنامهنویسان باید زبان مشترکی با متخصصان آن کسبوکار پیدا کنند تا نرمافزار دقیقاً نیازهای واقعی را پوشش دهد. در DDD، سیستم را به بخشهای کوچکتر و مستقل تقسیم شوند و برای هر بخش مدلسازی خاص خودش را انجام داده می شود. این کار باعث میشود کدهای نوشته شده دقیقاً بازتابدهنده فرآیندهای کسبوکار باشند و در صورت تغییر قوانین کسبوکار، تغییر کدها نیز منطقیتر و سادهتر باشد.این رویکرد انعطاف پذیری سامانه ما را در مقابل تغییرات افزایش می دهد.
معماری شش ضلعی با هدف جداسازی کامل منطق اصلی برنامه از فناوریهای بیرونی مثل دیتابیسها، رابطهای کاربری یا وبسرویسها طراحی شده است. در این معماری، هسته اصلی برنامه در مرکز قرار دارد و هیچ وابستگی مستقیمی به ابزارهای خارجی وجود ندارد. در عوض، ارتباط از طریق پورتها و آداپتورها انجام میشود. این یعنی اگر کسی بخواهد دیتابیس برنامه را از MySQL به MongoDB تغییر دهد یا رابط کاربری را عوض کند، نیازی به دستکاری کدهای اصلی برنامه ندارد. این رویکرد، تستپذیری و انعطافپذیری نرمافزار را به شدت افزایش میدهد.
در سیستمهای دیتابیس معمولی، معمولا همیشه آخرین وضعیت اطلاعات را ذخیره میشوند (مثلاً موجودی حساب ۱۰۰ تومان است). اما در Event Sourcing، به جای ذخیره وضعیت فعلی، تمام اتفاقات و رویدادهایی که باعث رسیدن به این وضعیت شدهاند را به ترتیب زمان ذخیره میشوند (مثلاً واریز ۵۰ تومان، واریز ۷۰ تومان، برداشت ۲۰ تومان). وضعیت نهایی با محاسبه مجدد این رویدادها به دست میآید. این روش، برگرفته از سیستم دفتر کل در حسابداری است. مزیت اصلی آن داشتن تاریخچه کامل و غیرقابل تغییر از تمام تغییرات سیستم است که برای حسابرسی، خطایابی و بازگردانی سیستم به یک نقطه زمانی خاص،مسیر را بسیار هموار خواهد کرد.
پلتفرمهای Low-code و No-code محیطهایی هستند که به افراد اجازه میدهند بدون نیاز به دانش برنامهنویسی عمیق یا با حداقل کدنویسی، اپلیکیشنهای کاربردی بسازند. این کار از طریق Drag and Drop المانهای بصری و اتصال آنها به یکدیگر انجام میشود. این پلتفرمها برای ساخت سریع ابزارهای درونسازمانی، اتوماسیون کارهای اداری و نمونهسازی اولیه بسیار عالی هستند. این ابزارها جایگزین برنامهنویسان حرفهای برای سیستمهای پیچیده نمیشوند، اما به کسبوکارها کمک میکنند تا ایدههای خود را با سرعت و هزینه بسیار کمتری به نرمافزار تبدیل کنند.یکی از این ابزار ها برنامه App Inventor می باشد که در جهت بازی سازی برای سیستم عامل های اندروید به کار برده می شود.
نرمافزارهای BPMS یا Business Process Management Systems ابزارهایی برای طراحی، اجرا، پایش و بهینهسازی فرآیندهای کاری در یک سازمان هستند.برای مثال فرآیند درخواست مرخصی در یک شرکت شامل تأیید مدیر مستقیم، منابع انسانی و در نهایت ثبت در سیستم حقوق است. با یک BPMS میتوان تمام این چرخه را به صورت گرافیکی مدلسازی کرد تا سیستم به طور خودکار فرمها را بین افراد جابهجا کند. این ابزارها شفافیت را در سازمان بالا میبرند، گلوگاههای کاری را مشخص میکنند و با حذف کاغذبازی و کارهای دستی، باعث افزایش چشمگیر راندمان کاری سازمان میشوند.
وقتی بخشهای مختلف یک نرمافزار میخواهند با هم حرف بزنند، گاهی یکی از آنها کندتر است یا موقتاً در دسترس نیست. صف پیام مانند یک صندوق پستی امن عمل میکند. سرویس فرستنده پیام خود را درون این صف میگذارد و به کار خود ادامه میدهد که به این روش ارتباط ناهمگام می گوییم. سیستمهای قدرتمندی مثل RabbitMQ یا Apache Kafka این پیامها را در صف نگه میدارند تا سرویس گیرنده هر زمان که توانست، آنها را بردارد و پردازش کند. این معماری باعث میشود در زمان ترافیکهای سنگین برای مثل روزهای حراج فروشگاهها، سیستم کِرَش نکند و درخواستها به نوبت و سر صبر پردازش شوند.
کانتینرها مانند Docker تکنولوژیهایی هستند که به ما اجازه میدهند برنامه و تمام نیازمندیهایش مانند کتابخانهها و تنظیمات مورد نیاز سامانه را در یک بسته مستقل و سبک قرار دهیم. با این کار، برنامه های سنتی که به اصطلاح “در کامپیوتر کار میکردند اما در سرور غیر فعال بودند” از بین میرود و برنامه همهجا یکسان اجرا میشود. نکته مهم اینجاست وقتی تعداد این کانتینرها به صدها یا هزاران عدد میرسد، مدیریت دستی آنها غیرممکن است. اینجاست که هماهنگکنندههایی مثل Kubernetes وارد میشوند. کوبرنتیز مدیریت روشن/خاموش کردن، مقیاسدهی خودکار و رفع خطای کانتینرها را به عهده میگیرد و سیستمی پایدار و توزیعشده میسازد تا بتوان به خوبی کانتینر هارا مدیریت نمود.
معماری Multi-Tenancy پایهی اصلی سرویسهای ابری SaaS است. در این معماری، یک نسخه واحد از نرمافزار روی سرور اجرا میشود، اما همزمان به چندین مشتری یا سازمان مختلف که به آنها Tenant میگویند خدمات میدهد. دادهها و تنظیمات هر مشتری کاملاً از دیگران جدا و ایزوله است، گویی که سیستم اختصاصی خودشان را دارند مثل کاری که نرمافزار جیمیل انجام می دهد. این روش برای شرکت توسعهدهنده به شدت مقرونبهصرفه است؛ زیرا به جای نگهداری صدها سرور برای صدها مشتری، فقط یک سرور و یک کد منبع را آپدیت و نگهداری میکند و منابع سختافزاری به اشتراک گذاشته میشوند.
مهاجرت دادهها به فرآیند انتقال اطلاعات از یک سیستم ذخیرهسازی، فرمت دیتابیس یا زیرساخت کامپیوتری به سیستمی دیگر گفته میشود. این اتفاق معمولاً زمانی رخ میدهد که شرکتها میخواهند سیستمهای نرمافزاری قدیمی خود را با نسخههای مدرن جایگزین کنند یا دادههایشان را از سرورهای فیزیکی به فضاهای ابری یا Cloud منتقل نمایند. این فرآیند بسیار حساس است، زیرا شامل استخراج دادهها، تبدیل و پاکسازی فرمت آنها و بارگذاری مجدد در سیستم جدید است. کوچکترین اشتباهی در این مسیر میتواند منجر به از دست رفتن اطلاعات حیاتی کسبوکار و خسارات سنگین شود.
این ۲۰ موضوع هر کدام بخشی از دنیای مدرن نرمافزار را نشان میدهند. بعضی از آنها بیشتر مربوط به معماری سیستم هستند، مثل DDD، CQRS، EDA و Hexagonal Architecture. بعضی دیگر به عملیات و استقرار مربوطاند، مثل IaC، Containers، Serverless و MLOps. بعضی از این موارد نیز به فرایندهای سازمانی و ابزارهای توسعه کمک میکنند، مثل BPMS، Low-code/No-code و Data Migration. هرچند هر کدام از این مفاهیم بهتنهایی قابل یادگیری هستند، اما در پروژههای واقعی معمولاً چند مورد از آنها با هم استفاده میشوند. داشتن یک شناخت اولیه از این مفاهیم کمک میکند بتوانیم سیستمها را بهتر درک کنیم، درباره آنها دقیق تر اظهار نظر کنیم و در آینده تصمیمهای فنی بهتری بگیریم.
منابع مورد بررسی در این مقاله:
Kubernetes Documentation
Docker Documentation
Istio Documentation
Martin Fowler: CQRS / Event Sourcing
HashiCorp Terraform Documentation
AWS Lambda Documentation
Kafka Documentation
RabbitMQ Documentation
Microsoft Architecture Center
Google Cloud / Azure / AWS official architecture docs