<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های مهدی مهدی پور</title><link>https://virgool.ir/feed/@mehdi.mehdipour21</link><description></description><language>fa</language><pubDate>2026-11-10 19:28:54</pubDate><image><url>https://virgool.ir/images/default-avatar.jpg</url><title>مهدی مهدی پور</title><link>https://virgool.ir/@mehdi.mehdipour21</link></image><item><title>آشنایی با معماری نرم‌ افزار با نگاهی به کتاب Head First Software Architecture</title><link>https://virgool.ir/@mehdi.mehdipour21/آشنایی-با-معماری-نرم-افزار-با-نگاهی-به-کتاب-head-first-software-architecture-ijq11odvkvxn</link><description>وقتی درباره ی توسعه ی نرم افزار صحبت می کنیم، ذهن ما بیشتر به سمت کد نویسی، انتخاب زبان برنامه نویسی، فریمورک ها و پیاده سازی قابلیت های سیستم می رود. اما هرچه یک نرم افزار بزرگ تر و پیچیده تر می شود، فقط خوب نوشتن کد برای موفقیت آن کافی نیست.در یک سیستم واقعی، تصمیم هایی وجود دارند که تأثیر آن ها بسیار بیشتر از یک کلاس یا یک تابع است. برای مثال، اینکه سیستم به صورت Monolithic طراحی شود یا Distributed، اینکه اجزای سیستم چگونه از یکدیگر جدا شوند، اینکه داده ها چگونه مدیریت شوند یا اینکه سیستم تا چه اندازه قابلیت توسعه و تغییر داشته باشد، همگی تصمیم هایی هستند که می توانند سال ها روی یک پروژه تأثیر بگذارند.این موضوع همان چیزی است که Software Architecture به آن می پردازد.در این مطلب قصد دارم برداشت خودم را از کتاب Head First Software Architecture بیان کنم و مفاهیم مهمی را که از این کتاب یاد گرفتم، مرور کنم. هدف این مطلب ارائه ی یک خلاصه از کتاب نیست؛ بلکه می خواهم مفاهیم اصلی آن را به شکلی توضیح دهم که برای افرادی که می خواهند درک بهتری از معماری سیستم ها داشته باشد، قابل استفاده باشد.معماری نرم افزار چیست؟یکی از نکات مهم در معماری نرم افزار این است که Architecture را نمی توان فقط به یک Diagram یا انتخاب یک Architecture Pattern محدود کرد. معماری نرم افزار مجموعه ای از تصمیم های مهم درباره ی ساختار یک سیستم است. برای مثال فرض کنید قرار است یک فروشگاه اینترنتی طراحی کنیم. در ابتدا شاید مسئله ساده به نظر برسد: کاربر محصول را انتخاب می کند، سفارش می دهد و هزینه را پرداخت می کند. اما وقتی سیستم بزرگ تر شود، سؤالات معماری زیادی مطرح می شوند:آیا کل سیستم یک برنامه ی واحد باشد؟آیا بخش های مختلف به سرویس های جداگانه تقسیم شوند؟اطلاعات کاربران و سفارش ها چگونه مدیریت شوند؟اگر تعداد کاربران افزایش پیدا کرد، سیستم چگونه Scale شود؟اگر یکی از بخش ها دچار مشکل شد، آیا کل سیستم از کار بیفتد؟تغییر یک قابلیت چقدر باید روی سایر قسمت های سیستم تأثیر بگذارد؟امنیت و احراز هویت چگونه در بخش های مختلف سیستم اعمال شود؟بنابراین معماری بیشتر از اینکه درباره ی چگونه کد نویسی باشد، درباره ی تصمیم های ساختاری و اثرات بلند مدت آن ها است. کتاب برای توضیح معماری نرم افزار، چند مفهوم را در کنار هم قرار می دهد: Architectural CharacteristicsArchitectural DecisionsLogical Components Architectural Stylesبه نظرم می توان این چهار مفهوم را به صورت یک زنجیره در نظر گرفت. ابتدا باید بدانیم یک سیستم چه ویژگی هایی نیاز دارد، بعد بر اساس آن ها تصمیم های معماری را بگیریم، اجزای منطقی سیستم را مشخص کنیم و در نهایت سبک معماری مناسب را انتخاب کنیم. بنابراین انتخاب معماری نباید از اینجا شروع شود که می خواهم از Microservices استفاده کنم؛ بلکه باید از این سؤال شروع شود که این سیستم چه نیازهایی دارد و چه ویژگی هایی برای آن مهم هستند؟در اینجا مفهوم Architectural Characteristics اهمیت پیدا می کند. این ویژگی ها مشخص می کنند سیستم از نظر فنی چه خصوصیاتی باید داشته باشد. ویژگی هایی مانند Performance، Scalability، Reliability، Maintainability و Security  نمونه هایی از همین Characteristics هستند. نکته ای که در این قسمت برای من جالب بود این است که نمی توان همه ی این ویژگی ها را هم زمان با بالاترین سطح ممکن در یک سیستم ایجاد کرد. اگر بخواهیم همه چیز را به بالاترین حد برسانیم، احتمالاً معماری بیش از حد پیچیده می شود و در نهایت با چیزی مواجه می شویم که اصطلاحاً Overengineering  شده است. بنابراین باید مشخص کنیم کدام ویژگی ها برای سیستم اهمیت بیشتری دارند و تصمیم های معماری را بر اساس همان اولویت ها بگیریم.اینجاست که یکی از مهم ترین مفاهیم کتاب یعنی Trade-off خودش را نشان می دهد. در معماری نرم افزار معمولاً یک انتخاب وجود ندارد که از همه ی جنبه ها بهترین باشد. تقریباً هر تصمیمی یک مزیت را افزایش می دهد و در مقابل ممکن است هزینه یا محدودیتی در جای دیگری ایجاد کند. برای مثال، Microservices می تواند استقلال سرویس ها و امکان Scale کردن بخش های مختلف سیستم را افزایش دهد، اما در مقابل پیچیدگی ارتباط بین سرویس ها، مدیریت داده، Consistency، Monitoring و Deployment را هم بیشتر می کند. بنابراین نمی توان به سادگی گفت Microservices بهتر از Monolith است. سؤال درست این است که برای این سیستم خاص، با این نیازها و محدودیت ها، کدام انتخاب Trade-off مناسب تری ایجاد می کند؟به همین دلیل یکی از ایده های مهم کتاب این است که در تصمیم های معماری، Why  از How مهم تر است. فرض کنیم در یک پروژه تصمیم گرفته ایم از Microservices استفاده کنیم. اینکه فقط بگوییم سیستم با Microservices طراحی شده اطلاعات چندانی درباره ی منطق این تصمیم به ما نمی دهد. اما اگر مشخص کنیم چرا این انتخاب انجام شده، چه مشکلی قرار بوده حل شود، چه گزینه هایی بررسی شده اند و چه هزینه هایی را پذیرفته ایم، تصمیم معماری ارزش بیشتری پیدا می کند. این مسئله مخصوصاً در پروژه های بلندمدت اهمیت دارد، چون ممکن است اعضای تیم در طول زمان تغییر کنند و توسعه دهندگان جدید وارد پروژه شوند. آن ها باید بتوانند دلیل پشت تصمیم های معماری را بفهمند، نه اینکه فقط با نتیجه ی آن تصمیم مواجه شوند.یکی از راه های ثبت همین تصمیم ها Architectural Decision Record  یا ADR است. ADR را می توان یک سند نسبتا کوتاه برای ثبت تصمیم های مهم معماری در نظر گرفت. در آن می توان  Context، تصمیم نهایی، گزینه های بررسی شده و پیامد های تصمیم را ثبت کرد. برای مثال اگر تیم تصمیم گرفته باشد یک سیستم را به صورت Modular Monolith طراحی کند، بهتر است مشخص شود چرا این گزینه انتخاب شده و چرا در آن مرحله Microservices انتخاب نشده است. این اطلاعات ممکن است در زمان تصمیم گیری ساده به نظر برسند، اما چند ماه یا چند سال بعد می توانند بسیار ارزشمند باشند.بعد از تصمیم گیری درباره ی ساختار کلی سیستم، مسئله ی تقسیم سیستم به اجزای مختلف مطرح می شود. اینجا مفاهیمی مثل  Coupling وCohesion اهمیت پیدا می کنند. Coupling به میزان وابستگی بین اجزای سیستم مربوط است. اگر دو بخش وابستگی زیادی به یکدیگر داشته باشند، تغییر در یکی از آن ها می تواند بخش دیگر را هم تحت تأثیر قرار دهد. در مقابل، Cohesion  به این موضوع مربوط می شود که مسئولیت های مرتبط تا چه اندازه در کنار هم قرار گرفته اند. در یک طراحی مناسب معمولاً به دنبال Cohesion  بالا و Coupling کنترل شده هستیم؛ یعنی هر بخش مسئولیت مشخص و مرتبطی داشته باشد و در عین حال وابستگی غیر ضروری آن به بخش های دیگر کاهش پیدا کند. این موضوع در پروژه های بزرگ اهمیت بیشتری پیدا می کند، چون با افزایش تعداد اجزای سیستم، مدیریت وابستگی ها سخت تر می شود.بعد از این مفاهیم، کتاب وارد بحث Architecture Styles  می شود. این قسمت برای من جذاب بود، چون سبک های مختلف معماری را نه به صورت یک فهرست از Patternها، بلکه در قالب یک Landscape بررسی می کند. در این Landscape دو محور اصلی وجود دارد. محور افقی به نحوه ی تقسیم بندی سیستم مربوط می شود؛ در یک طرف Technical Partitioning  قرار دارد و در طرف دیگر Domain Partitioning.  در Technical Partitioning سیستم بیشتر بر اساس مسئولیت های فنی تقسیم می شود، در حالی که در Domain Partitioning  تقسیم بندی بر اساس قابلیت ها یا حوزه های کسب و کار انجام می شود.محور عمودی هم نحوه ی Deployment را نشان می دهد؛ از Monolithic Deployment  در پایین تا Distributed Deployment  در بالا. با ترکیب این دو محور، می توان جایگاه سبک هایی مانند Layered Architecture، Modular Monolith، Microkernel و Microservices را بهتر درک کرد.در Layered Architecture  سیستم معمولاً بر اساس لایه های فنی تقسیم می شود. برای مثال ممکن است لایه های Presentation، Business و Persistence داشته باشیم. این معماری به دلیل سادگی و قابل فهم بودن، در بسیاری از سیستم ها انتخاب مناسبی است، اما در سیستم های بزرگ ممکن است یک تغییر در قابلیت های کسب و کار باعث شود مجبور شویم چند لایه ی مختلف را تغییر دهیم. در مقابل، Modular Monolith  تلاش می کند سیستم را بیشتر بر اساس Domain یا قابلیت های کسب و کار تقسیم کند، در حالی که کل سیستم همچنان به صورت یک واحد Deploy می شود. مثلاً در یک فروشگاه اینترنتی می توان Module های جداگانه ای برای User، Product، Order  و Payment داشت. این موضوع یک نکته ی مهم را نشان می دهد: برای داشتن یک ساختار ماژولار، لزوماً لازم نیست از همان ابتدا سیستم را به Microservices  تبدیل کنیم.در طرف دیگر، با سبک هایی مواجه می شویم که بیشتر به سمت Distributed Deployment می روند. Microkernel  از یک Core System تشکیل می شود که قابلیت های مختلف می توانند به صورت Plugin  در اطراف آن قرار بگیرند. این مدل برای سیستم هایی که قابلیت توسعه یا سفارشی سازی بالایی دارند می تواند مفید باشد. Microservices نیز سیستم را به سرویس های مستقل تری تقسیم می کند که معمولاً هر کدام مسئول یک حوزه یا قابلیت مشخص هستند. در یک فروشگاه اینترنتی می توان سرویس هایی مانند User Service، Product Service، Order Service و Payment Service داشت. مزیت این روش می تواند استقلال بیشتر سرویس ها و امکان Scale کردن آن ها باشد، اما همان طور که در بحث Trade-off گفتیم، Distributed  شدن سیستم هزینه هایی هم دارد. ارتباطات شبکه ای، مدیریت داده، Failure  بین سرویس ها، Consistency  و پیچیدگی Deployment از جمله مسائلی هستند که باید در نظر گرفته شوند. بنابراین Microservices را نمی توان صرفاً نسخه ی بهتر Monolith دانست.این موضوع باعث می شود به یک سؤال مهم برسیم:  چه زمانی باید Monolith انتخاب کنیم و چه زمانی Distributed Architecture؟ به نظر من یکی از پیام های مهم کتاب همین است که نباید صرفاً به دلیل محبوب بودن یک تکنولوژی یا Architecture Style آن را انتخاب کنیم. برای یک پروژه ی کوچک ممکن است یک Monolith ساده بهترین انتخاب باشد. برای پروژه ای که Domain پیچیده تری دارد، Modular Monolith می تواند ساختار مناسبی ایجاد کند و در عین حال پیچیدگی سیستم Distributed را وارد پروژه نکند. در مقابل، در بعضی سیستم های بزرگ و پیچیده، Microservices می تواند مزایای قابل توجهی داشته باشد. بنابراین انتخاب معماری باید از نیازهای واقعی سیستم شروع شود، نه از علاقه ی تیم به یک تکنولوژی خاص.کتاب در ادامه یک مسیر برای تصمیم گیری معماری پیشنهاد می کند. ابتدا باید Architectural Characteristics  مورد نیاز سیستم را شناسایی کنیم. سپس Components  اصلی را مشخص کنیم و مسئولیت های آن ها را در نظر بگیریم. بعد از آن می توان Architecture Style مناسب را انتخاب کرد. تصمیم گرفته شده باید مستند شود و در نهایت معماری را می توان با Diagramهای مناسب نمایش داد. این فرآیند برای من جالب بود، چون نشان می دهد معماری یک تصمیم لحظه ای نیست؛ بلکه مجموعه ای از مراحل تحلیل، انتخاب، مستند سازی و ارتباط تصمیم هاست.در نهایت، کتاب فقط درباره ی تکنولوژی ها و  Architecture Styleها صحبت نمی کند و به خود نقش Software Architect  هم توجه دارد. تصویری که کتاب از یک معمار نرم افزار ارائه می کند، صرفاً یک فرد متخصص در یک تکنولوژی خاص نیست. یک Software Architect بایدTechnical Breadth  داشته باشد و با حوزه های مختلف فنی آشنا باشد. در عین حال نباید ارتباطش را با کد نویسی از دست بدهد، چون درگیری با کد و مشکلات واقعی پیاده سازی به تصمیم های معماری کمک می کند. در کنار این موارد، Soft Skills هم اهمیت زیادی دارند. یک تصمیم معماری زمانی ارزشمند است که بتوان آن را برای اعضای تیم توضیح داد، درباره ی آن مذاکره کرد و دلیل انتخاب آن را به شکل مناسبی منتقل کرد.اگر بخواهم تمام مطالب کتاب را در چند نکته خلاصه کنم، اولین نکته برای من این است که Architecture همیشه Contextual است. یعنی یک معماری خوب برای همه ی سیستم ها وجود ندارد و انتخاب مناسب به شرایط همان سیستم بستگی دارد. نکته ی دوم این است که در معماری نرم افزار باید Trade-offها را پذیرفت. هر انتخابی هزینه ای دارد و وظیفه ی مهندس نرم افزار این نیست که دنبال یک راه حل کاملاً بدون نقص بگردد؛ بلکه باید بتواند هزینه و فایده ی گزینه های مختلف را مقایسه کند. نکته ی سوم هم اهمیت مستندسازی و دفاع از تصمیم های معماری است. وقتی دلیل تصمیم ها ثبت شده باشد، معماری برای اعضای فعلی و آینده ی تیم قابل فهم تر خواهد بود.در آخر شاید بتوان پیام اصلی کتاب را این طور خلاصه کرد: معماری نرم افزار درباره ی پیدا کردن یک راه حل کامل نیست؛ درباره ی گرفتن تصمیم های آگاهانه و درک پیامد های آن ها است. همین نگاه است که باعث می شود معماری به یکی از مهم ترین بخش های مهندسی نرم افزار تبدیل شود.اين مطلب، بخشي از تمرينهاي درس معماري نرم افزار در دانشگاه شهيد بهشتي است.</description><category>مهدی مهدی پور</category><author>مهدی مهدی پور</author><pubDate>Tue, 11 Aug 2026 16:00:19 +0330</pubDate></item><item><title>پنج سخنرانی مفید در حوزه معماری نرم افزار</title><link>https://virgool.ir/@mehdi.mehdipour21/پنج-سخنرانی-مفید-در-حوزه-معماری-نرم-افزار-xfyenijknunj</link><description>&#xA;1.      Software Architectures, Team Topologies, and Complexity Scienceجیمز لوئیس کسی که مفهوم میکروسرویس را معروف کرد در این سخنرانی به یک سوال اساسی جواب می‌دهد: راز تیم ‌های نرم ‌افزاری فوق‌ موفق چیست؟ او برای جواب دادن، سه تا علم را به هم وصل می‌کند: علم پیچیدگی، معماری نرم‌افزار، و چیدمان تیم‌ هاجیمز می‌گوید که یک کلونی مورچه را در نظر بگیرید. هر مورچه به ‌تنهایی کار ساده ‌ای می‌کند، اما وقتی همه کنار هم قرار می‌گیرند، یک رفتار با هوش از کل کلونی دیده می‌شود که هیچ‌ کس از بالا دستور نداده است. تیم‌ های نرم‌ افزاری هم دقیقا همینطور هستند. یک معمار نباید از بالا همه جزئیات را برای تیم تعیین کند، بلکه باید شرایط را طوری فراهم کند که خود تیم‌ ها با تعاملات ساده‌ ، بهترین راه‌ حل را پیدا کنند.در ادامه به مدل معروف توپولوژی تیم اشاره می‌کند که می‌گوید تیم‌ ها را باید به چهار دسته تقسیم کرد: ۱) تیم هایی که مستقیما برای کاربر ارزش میسازند، ۲) تیم هایی که به بقیه آموزش میدهند، ۳) تیم هایی که در بخش زیر ساخت فعالیت دارند، و ۴) تیم هایی که بخش های خیلی سخت سیستم را مدیریت میکنند. همچنین مشخص می‌کند که این تیم ‌ها چطور با هم تعامل داشته باشند؛ مثلاً با هم همکاری کنند یا به هم سرویس بدهند. این مدل به ما یک زبان مشترک می‌دهد تا بفهمیم چرا یک تیم با تیم دیگر مشکل دارد.نکته‌ی کلیدی این است که ساختار تیم ‌ها، معماری نرم‌ افزار را می‌سازد. اگر تیم ‌ها را بر اساس کارهایی که انجام می‌دهند (مثل ثبت‌نام یا پرداخت) بچینید، معماری نرم ‌افزار هم به‌ طور طبیعی به بخش‌ های کوچک و مستقل (میکروسرویس) تبدیل می‌شود. هدف نهایی از همه این کارها، بهبود جریان (Flow) است، یعنی کد جدید هر چه سریع ‌تر و با کمترین دردسر به دست کاربر برسد.این سخنرانی به ما میگوید که معمار نرم‌ افزار فقط نقشه‌کش نیست در واقع یک معمار خوب باید مثل یک باغبان باشد که خاک را آماده می‌کند و به تیم‌ها که در این مثال همان گیاهان هستند اجازه می‌دهد خودشان رشد کنند و تعاملات درستی با هم داشته باشند. معماری خوب، فقط کد تمیز نیست و حاصل تعاملات انسانیِ خوب است.سخنران: James Lewisلینک: https://www.youtube.com/watch?v=TgFSdEP9gcc 2.      Software Design, Architecture &amp; Giving Clarity at Scaleاین سخنرانی یک مصاحبه است، یعنی سه نفر نشستند پای میز و با هم حرف زدند. موضوعش هم خیلی جالبه: وقتی تیم نرم ‌افزاری کوچیکه، همه با همه حرف می‌زنند و همه می‌دانند که کد کجاست و چرا فلان جور نوشته شده. اما وقتی شرکت بزرگ می‌شود و تیم ‌ها به بیست تا چهل تیم مختلف تبدیل می‌شوند، اوضاع خیلی فرق می‌کند. توی این شرایط، بزرگ‌ ترین مشکل، خود کد نویسی نیست؛ مشکل این است که تیم‌ ها دیگر متوجه نمیشوند که معماری کلی سیستم دقیقا چیست و چرا بعضی تصمیمات گرفته شده است.سم نیومن توی این صحبت می‌گوید که وظیفه یک معمار نرم ‌افزار در این مقیاس بزرگ، فقط کشیدن نقشه پشت‌ سر هم نیست. او باید طوری حرف بزند که هم مدیر عامل شرکت که می‌خواهد بداند چقدر زمان می‌برد متوجه شود، هم برنامه ‌نویس تازه ‌وارد که می‌خواهد بداند کد جدید را کجای پروژه بنویسد متوجه شود. به‌عبارتی، معمار باید مثل یک مترجم عمل کند.یکی از نکات جالبی که جکی رید گفت این بود که خیلی از مشکلات معماری، ریشه در نگاه‌ های متفاوت دارد. مثلا تیم پشتیبانی به قابلیت ثبت ‌نام کاربر به‌عنوان فرم ورود اطلاعات نگاه می‌کند، ولی تیم امنیت به ‌عنوان ریسک نفوذ نگاه می‌کند. اگر معمار نتواند این اختلاف نگاه را مدیریت کند و به همه بگوید که هدف نهایی چیست، آنوقت طراحی عالی‌ ترین سیستم هم به ‌مرور زمان تبدیل به چیزی می‌شود که هیچ‌ کس از آن سر در نمی‌آورد.اگر می‌خواهیم یک معمار خوب شویم، باید اول از همه ارتباطات و گوش دادن را یاد بگیریم. وقتی یک تصمیم معماری می‌گیریم، باید بتوانیم آن را به زبان خیلی ساده برای یک مدیر کسب‌ و کار توضیح بدهیم و همچنین بتوانیم آن را به شکل دقیق فنی برای تیم برنامه ‌نویسی تشریح کنیم.سخنران: Sam Newman, Jacqui Read, Simon Rohrerلینک: https://www.youtube.com/watch?v=Gp5KjP3tFJU 3.      Adaptive Architectures: Reimagining API Federation &amp; Microservices Integrationبا گسترش استفاده از معماری میکروسرویس، یکی از چالش‌های مهم تیم ‌های توسعه، برقراری ارتباط بین سرویس‌ های متعدد است. در بسیاری از پروژه ‌ها برای اتصال سرویس‌ ها، حجم زیادی از کد های واسط (Glue Code) نوشته می‌شود که وظیفه تبدیل داده ‌ها، فراخوانی APIها و هماهنگ ‌سازی سرویس‌ ها را بر عهده دارند. اگرچه این روش در ابتدا ساده به نظر می‌رسد، اما با بزرگ‌تر شدن سیستم، نگهداری این کد ها دشوار شده و کوچک‌ترین تغییر در یک سرویس می‌تواند باعث ایجاد تغییرات زنجیره ‌ای در بخش‌های مختلف سیستم شود.این مشکل الزاما ناشی از معماری مایکروسرویس نیست، بلکه به شیوه‌ی طراحی ارتباط میان سرویس‌ها مربوط می‌شود. ایده‌ی اصلی این است که به جای نوشتن کد های زیاد برای اتصال سرویس ‌ها، باید مشخصات APIها مانند OpenAPI و gRPC را به عنوان بخش اصلی معماری در نظر گرفت. در این صورت، سیستم می‌تواند بسیاری از ارتباطات را به صورت خودکار مدیریت کند و وابستگی میان سرویس‌ ها کاهش یابد.یکی از نکات جالب این ارائه معرفی زبان Taxi است. این زبان امکان اضافه کردن اطلاعات معنایی به APIها را فراهم می‌کند. در نتیجه، سیستم تنها نام فیلدها یا نوع داده‌ها را نمی‌شناسد، بلکه مفهوم واقعی آن‌ها را نیز درک می‌کند. به کمک این اطلاعات، موتور اجرای TaxiQL قادر است بدون نیاز به نوشتن حجم زیادی از کد، سرویس‌های مناسب را پیدا کرده و آن‌ها را برای پاسخ به یک درخواست با یکدیگر ترکیب کند.به نظر من آینده‌ ی معماری نرم‌ افزار به سمت کاهش وابستگی به کد نویسی دستی حرکت می‌کند. در بسیاری از پروژه ‌ها، توسعه ‌دهندگان زمان زیادی را صرف نوشتن کدهایی می‌کنند که ارزش تجاری مستقیمی برای محصول ایجاد نمی‌کنند و تنها برای اتصال اجزای مختلف سیستم مورد استفاده قرار می‌گیرند. اگر بتوان این فرآیند را با استفاده از استانداردها و ابزارهای هوشمند خودکار کرد، علاوه بر کاهش هزینه توسعه، سرعت تغییرات نیز افزایش پیدا خواهد کرد.موضوع مهم دیگری که Marty Pitt به آن اشاره می‌کند، مفهوم Adaptive Architecture یا معماری تطبیق‌پذیر است. در چنین معماری ‌ای، سیستم می‌تواند خود را با تغییرات محیط، نسخه‌های جدید APIها یا اضافه شدن سرویس ‌های تازه سازگار کند، بدون آنکه نیاز به بازنویسی گسترده کد وجود داشته باشد. این ویژگی برای سازمان‌هایی که ده‌ها یا صدها مایکروسرویس دارند، اهمیت بسیار زیادی دارد؛ زیرا در این مقیاس، مدیریت وابستگی‌ها به یکی از بزرگ‌ترین چالش‌های تیم ‌های فنی تبدیل می‌شود.سخنران: Marty Pittلینک ویدئو: https://www.youtube.com/watch?v=VjaM0l55Inc 4.      Software Architecture: The Hard Partsمعمولا وقتی اسم معماری نرم فزار را میشنویم به انتخاب فناوری ‌ها یا طراحی بخش ‌های مختلف یک سیستم فکر می‌کنیم. اما این سخنرانی نشان می‌دهد که سخت ‌ترین قسمت معماری، انتخاب یک فناوری یا کشیدن چند نمودار نیست. به گفته او، بخش دشوار کار این است که بتوان بین چند راه‌حل مختلف تصمیم درستی گرفت؛ چون در بیشتر مواقع هیچ راه ‌حل کاملا درست یا کاملا اشتباهی وجود ندارد.یکی از نکاتی که در این سخنرانی بیشتر از همه توجه من را جلب کرد، این بود که معمار نرم ‌افزار همیشه باید بین مزایا و معایب گزینه‌ های مختلف تعادل برقرار کند. مثلا ممکن است یک روش باعث شود برنامه سریع ‌تر اجرا شود، اما در عوض نگهداری آن سخت‌ تر شود. یا برعکس، ممکن است روشی وجود داشته باشد که توسعه آن ساده ‌تر باشد، اما هزینه بیشتری داشته باشد. بنابراین تصمیم گرفتن همیشه ساده نیست و باید شرایط پروژه را در نظر گرفت.در ادامه توضیح می‌دهد که هیچ معماری ‌ای برای همه پروژه ‌ها مناسب نیست. چیزی که برای یک شرکت بزرگ جواب می‌دهد، ممکن است برای یک پروژه کوچک اصلاً انتخاب خوبی نباشد. به همین دلیل، معمار باید قبل از هر تصمیم، نیازهای واقعی پروژه را بشناسد و فقط به خاطر محبوب بودن یک فناوری یا روش، از آن استفاده نکند.بخش دیگری از سخنرانی درباره تغییرات پروژه بود. تقریباً هیچ نرم ‌افزاری وجود ندارد که بعد از انتشار دیگر تغییری نکند. نیازهای کاربران عوض می‌شود، امکانات جدید اضافه می‌شود و حتی گاهی کل مسیر پروژه تغییر می‌کند. به همین دلیل معماری باید به گونه ‌ای باشد که این تغییرات را راحت‌ تر بپذیرد. اگر از همان ابتدا همه چیز بیش از حد پیچیده طراحی شود، بعدا ایجاد تغییرات زمان و هزینه زیادی خواهد داشت.یکی دیگر از نکات جالب سخنرانی این بود که تصمیم‌ های معماری نباید فقط در ذهن یک نفر باقی بمانند و پیشنهاد می‌کند که دلیل انتخاب هر تصمیم ثبت شود تا اعضای تیم در آینده بدانند چرا آن تصمیم گرفته شده است. این کار باعث می‌شود اگر چند ماه یا چند سال بعد لازم باشد تغییری ایجاد شود، افراد راحت‌تر بتوانند وضعیت پروژه را درک کنند.سخنران:  Neal Fordلینک ویدئو: https://www.youtube.com/watch?v=x3Ay6yBoclo 5.      Democratising Software Architectureاین سخنرانی توضیح می‌دهد که معماری نرم‌ افزار دیگر نباید کار یک نفر باشد، بلکه باید توسط تمام اعضای تیم به اشتراک گذاشته شود. او با معرفی ایده‌ی Continuous Architecture نشان می‌دهد چگونه رویکردهای  Agile و DevOps معماری را به یک کار تیمی تبدیل کرده‌اند.Woods  تاریخچه‌ ای از معماری نرم ‌افزار ارائه می‌دهد و می‌گوید در گذشته معمولاً یک معمار یا گروه کوچکی از متخصصان در ابتدا طراحی معماری را انجام می‌دادند و مستندات سنگین می‌ نوشتند. اما امروزه با آمدن  DevOps، Cloud  و توسعه اجایل و میکروسرویس‌ ها، چرخه‌ های انتشار سریع‌ تر شده و نیازها دائماً تغییر میکنند. بنابراین تصمیم‌ های معماری نباید همه در ابتدا گرفته شود؛ بلکه معماری باید هر چند وقت یک ‌بار بازنگری و اصلاح شود.او می‌گوید امروزه تیم‌ های توسعه خودگردان و کوچک می‌توانند بسیاری از تصمیم‌ها را بگیرند، پس بهتر است معماری به عنوان مهارتی عمومی در تیم در نظر گرفته شود نه نقش یک نفر. در این رویکرد، اسناد معماری حجیم جای خود را به دیاگرام‌ های ساده و یاد داشت‌های سبک داده ‌اند و تیم‌ ها از ابزار های نظارتی برای فهم معماری پویا استفاده می‌کنند. به عبارت دیگر، معماری باید پیوسته کنار کد توسعه داده شود؛ یعنی هر اسپرینت یا در هر مرحله از توسعه، نگاهی دوباره به معماری داشته باشیم.یکی از مفاهیم کلیدی این سخنرانی این بود که معماری یک shared commons است. همچنین تاکید می‌کند که این روش باعث می‌شود تیم‌ ها با هم بهتر کار کنند و پروژه‌ ها نتایج بهتری داشته باشند  این دیدگاه جدید نشان می‌دهد که چالش معماری امروز بیشتر در نحوه تصمیم‌گیری و تیم‌ بندی است تا در انتخاب فناوری‌های خاص. وقتی همه اعضای تیم در جریان معماری قرار می‌گیرند، می‌توانند سریع‌تر ویژگی‌های جدید اضافه کنند و بهتر به نیازهای مشتریان واکنش نشان دهند.سخنران : Eoin Woodsلینک :  https://www.youtube.com/watch?v=nchRmYvUf2Yاين مطلب، بخشي از تمرينهاي درس معماري نرم‌افزار در دانشگاه شهيدبهشتي است#معماري_نرم_افزار_بهشتي #معماری_نرم افزار</description><category>مهدی مهدی پور</category><author>مهدی مهدی پور</author><pubDate>Fri, 10 Jul 2026 13:08:33 +0330</pubDate></item><item><title>آشنایی با ۲۰ مفهوم مهم در معماری نرم‌ افزار مدرن</title><link>https://virgool.ir/@mehdi.mehdipour21/آشنایی-با-۲۰-مفهوم-مهم-در-معماری-نرم-افزار-مدرن-ifiddrutavfe</link><description>در معماری نرم افزار، صرفا دانستن برنامه نویسی یا کار با یک زبان خاص کافی نیست چون زمانی که یک سیستم نرم افزاری بزرگتر می شود، موضوعاتی مثل مقیاس پذیری، نگهداری، امنیت، استقرار، ارتباط بین سرویس ها، مدیریت داده، کیفیت سرویس و هماهنگی بین تیم ها و سایر موارد اهمیت زیادی پیدا می کنند. مفاهیمی که در اینجا بررسی می شوند، بیشتر به همین بخش های پیشرفته تر و عملی تر  مربوط هستند؛ یعنی جاهایی که نرم افزار از یک برنامه ساده خارج می شود و به یک سیستم واقعی، توزیع شده، قابل توسعه و قابل بهره برداری تبدیل می شود.هدف از توضیح این مفاهیم این است که یک شناخت اولیه و کاربردی نسبت به اصطلاحاتی داشته باشیم که در پروژه های نرم افزاری مدرن زیاد شنیده می شوند. ممکن است در آینده هنگام طراحی یک سیستم، کار در یک تیم نرم افزاری، مطالعه مستندات فنی یا حتی تحلیل یک معماری موجود، با این واژه ها رو به رو شویم. بنابراین لازم نیست در این مرحله متخصص کامل هر موضوع باشیم، اما باید بتوانیم مفهوم کلی، کاربرد، مزایا، محدودیت ها و جایگاه هر کدام را در معماری نرم افزار درک کنیم. این تمرین کمک می کند دید ما از نرم افزار فقط در سطح کد و پیاده سازی باقی نماند و بتوانیم نرم افزار را به عنوان یک سیستم کامل شامل طراحی، زیرساخت، عملیات، داده و نیازهای کسب و کار ببینیم.1.      Chaos Engineeringاگر بخواهم Chaos Engineering را خیلی ساده توضیح بدهم، می گویم این رویکرد یعنی ما به صورت کنترل شده و آگاهانه به سیستم فشار می آوریم تا بفهمیم در دنیای واقعی چقدر مقاوم است. ایده اصلی این نیست که سیستم را بی هدف خراب کنیم، بلکه هدف این است که با اجرای آزمایش روی یک سامانه توزیع شده، به قابلیت آن برای تحمل شرایط آشفته، غیر منتظره و نامطلوب اعتماد پیدا کنیم.در این رویکرد، ابتدا باید رفتار پایدار سیستم مشخص شود سپس باید فرضیه ای بسازیم که سیستم در شرایط نامطلوب نیز بتواند همان رفتار پایدار را حفظ کند. بعد از آن، رخداد هایی نزدیک به دنیای واقعی، مانند افزایش تأخیر شبکه، قطع یک وابستگی، از کار افتادن نمونه های اجرایی یا افزایش ناگهانی بار، شبیه سازی می شوند.در واقع ما عمداً و کنترل شده در سیستم اختلال ایجاد کنیم تا ببینیم سیستم در شرایط خراب و غیر منتظره چقدر مقاوم است.در دنیای واقعی، سیستم ها همیشه در حالت ایده آل کار نمی کنند. ممکن است سرور قطع شود، اینترنت کند شود، دیتابیس از دسترس خارج شود یا یک سرویس دیر جواب بدهد. این رویکرد کمک می کند قبل از اینکه این مشکلات در محیط واقعی و برای کاربران اتفاق بیفتند، خودمان آن ها را شبیه سازی کنیم.مثلاً فرض کنیم یک فروشگاه اینترنتی داریم. اگر سرویس پرداخت برای چند دقیقه قطع شود، آیا کل سایت از کار می افتد؟ یا فقط بخش پرداخت خطا می دهد و بقیه سایت همچنان کار می کند؟ Chaos Engineering این سناریو ها را بررسی می کند. هدف آن خراب کردن سیستم نیست؛ هدف این است که بفهمیم سیستم در برابر خرابی ها چقدر آماده است.2.      Backend for Frontendمعمولا یک سیستم ممکن است چند نوع فرانت اند داشته باشد؛ مثلا وب سایت، اپلیکیشن موبایل اندروید، اپلیکیشن iOS یا پنل مدیریتی که هر کدام از این ها ممکن است داده ها را به شکل متفاوتی نیاز داشته باشند.در روش سنتی، همه این فرانت اند ها به یک بک اند مشترک وصل می شوند که گاهی اوقات اینکار باعث پیچیدگی بیشتر می شود، چون نیازهای موبایل با وب فرق دارد.الگوی BFF یعنی به جای این که یک بک اند عمومی داشته باشیم که هم زمان بخواهد نیازهای وب، موبایل، پنل مدیریت و هر کلاینت دیگری را پوشش بدهد، برای هر فرانت اند یک بک اند اختصاصی می سازیم.نتیجه این کار کاهش دریافت بیش از اندازه داده، کاهش کمبود داده در پاسخ ها و کم شدن پیچیدگی سمت کلاینت است. مثلا اپلیکیشن موبایل فقط به اطلاعات خلاصه محصول نیاز دارد، ولی نسخه وب ممکن است توضیحات کامل، نظرات، تصاویر زیاد و پیشنهادهای مرتبط را هم بخواهد. با BFF می توان برای موبایل یک API سبک تر و سریع تر ساخت.3.      AI4SEAI4SE  مخفف Artificial Intelligence for Software Engineering میباشد و به معنی استفاده از هوش مصنوعی برای بهتر انجام دادن فعالیت های مهندسی نرم افزار. در گذشته بسیاری از کارهای برنامه نویسی، تست، نگهداری و تحلیل کد کاملا دستی انجام می شدند. اما امروزه با رشد مدل های یادگیری ماشین و مخصوصاً مدل های زبانی بزرگ، می توان بخشی از این کارها را هوشمند تر یا نیمه خودکار کرد. مثلاً ابزارهای پیشنهاد کد، تولید تست، تشخیص باگ، تحلیل کدهای قدیمی، توضیح کد و حتی کمک در طراحی معماری، نمونه هایی از AI4SE هستند.اینکار مستقیما روی بهره وری توسعه دهندگان اثر می گذارد به عنوان مثال یک برنامه نویس ممکن است با کمک ابزار هوشمند سریع تر کد بنویسد، ولی همچنان مسئول درک، بررسی و اصلاح خروجی است چون خروجی هوش مصنوعی همیشه درست نیست و ممکن است مشکلات امنیتی، منطقی یا کارایی وجود داشته باشد و به همین دلیل بیشتر به عنوان یک دستیار برای مهندسان نرم افزار عمل میکند.4.      SE4AI SE4AI (Software Engineering for Artificial Intelligence) به کارگیری اصول مهندسی نرم افزار برای توسعه، استقرار و نگهداری سیستم هایی است که درون خود مؤلفه هوش مصنوعی دارند. در مقابل، AI4SE  استفاده از خود هوش مصنوعی برای بهبود فرایندهای مهندسی نرم افزار (مثل کدنویسی خودکار، تست هوشمند) است. اما SE4AI یک پرسش بنیادی دارد: چگونه یک سیستم مبتنی بر AI را چنان مهندسی کنیم که قابل اعتماد، قابل نگهداری، مقیاس پذیر و قابل تست باشد؟ساخت یک مدل هوش مصنوعی فقط به آموزش مدل خلاصه نمی شود. مراحل کامل آن شامل جمع آوری داده، پاکسازی داده، آموزش مدل، تست، نسخه بندی، استقرار در محیط واقعی و مانیتورینگ پس از اجراست. SE4AI تلاش می کند تا تمام این مراحل را اصولی، مستند، خودکار و قابل تکرار کند تا سیستم نهایی در برابر تغییرات داده و محیط، رفتاری باثبات و قابل پیش بینی داشته باشد.5.      MLOpsMLOps  از ترکیب دو مفهوم Machine Learning و DevOps به وجود آمده و هدف اصلی آن مدیریت و بهینه ‌سازی چرخه عمر مدل ‌های یادگیری ماشین است. همان ‌طور که دواپس به دنبال ایجاد هماهنگی بیشتر بین تیم‌ های توسعه و عملیات است، MLOps  نیز تلاش می‌کند فرایند های مربوط به ساخت، آزمایش، استقرار و نظارت بر مدل ‌های یادگیری ماشین را استاندارد و قابل تکرار کند.به نظر من MLOps برای جلوگیری از آشفتگی در پروژه‌ های هوش مصنوعی ضروری است چون در این پروژه‌ ها علاوه بر کد، داده و مدل هم دارایی اصلی هستند. اگر نسخه داده مشخص نباشد یا ندانیم یک مدل با چه تنظیماتی آموزش دیده، باز تولید نتیجه تقریباً غیرممکن می‌شود. علاوه بر این، مدل‌ های هوش مصنوعی برخلاف نرم‌ افزارهای سنتی ممکن است با تغییر داده‌ های ورودی به مرور زمان دچار افت عملکرد شوند و به همین دلیل، بررسی مداوم مدل‌ ها و مدیریت صحیح فرایند های مرتبط با انها از طریق MLOps می‌تواند به حفظ کیفیت و پایداری سیستم کمک کند.6.      Infrastructure as Code (IaC) IaC یعنی به جای اینکه تنظیمات سرورها و زیر ساخت را به صورت دستی انجام بدیم، همه چیز را در قالب کد و فایل بنویسیم. در روش قدیمی، یک مدیر سیستم باید خودش وارد پنل شود و سرورها، شبکه، پایگاه داده و تنظیمات مختلف را یکی‌یکی ایجاد کند. این کار هم زمان‌بر است و هم ممکن است باعث اشتباه شود.در IaC همه این تنظیمات به صورت کد نوشته می‌شوند و در مخزن‌هایی مثل Git ذخیره می‌شوند و به این ترتیب هر زمان که بخواهیم می‌توانیم همان زیرساخت را دوباره و بدون دردسر ایجاد کنیم.به نظر من مهم‌ترین مزیت IaC این است که چون همه تغییرات ثبت می‌شوند مدیریت زیرساخت را ساده‌تر می‌کند و می‌توان تغییرات را بررسی کرد یا در صورت نیاز به نسخه قبلی برگشت. همچنین ساخت محیط‌های مشابه برای تست یا اجرا خیلی راحت‌تر می‌شود.7.      API Gateway &amp; Service Meshاین دو مورد برای مدیریت ارتباطات میکروسرویس در سیستم های مدرن استفاده می‌شوند، اما کاربردشان با هم متفاوت است که در ادامه بررسی میکنیم.API Gateway  در واقع در ورودی سیستم قرار می‌گیرد یعنی وقتی کاربر از طریق سایت یا اپلیکیشن درخواستی ارسال می‌کند، ابتدا این درخواست به API Gateway می‌رسد و بررسی میشود که کاربر مجاز است یا نه، سپس درخواست را به سرویس مناسب می‌فرستد و گاهی اطلاعات لازم را جمع‌آوری و مدیریت می‌کند. به زبان ساده، API Gateway مثل درب ورودی یک ساختمان است که همه باید از آن عبور کنند.اما Service Mesh داخل سیستم کار می‌کند، در معماری مایکروسرویس، سرویس‌های مختلف دائماً با یکدیگر در ارتباط هستند. Service Mesh کمک می‌کند این ارتباطات به شکل امن‌تر و منظم‌تر انجام شوند. همچنین کارهایی مثل مدیریت خطاها، توزیع ترافیک و نظارت بر ارتباط بین سرویس‌ها را ساده‌تر می‌کند.به نظر من تفاوت اصلی این دو در این است که API Gateway درخواست‌های ورودی از کاربران را مدیریت می‌کند، اما Service Mesh ارتباط بین سرویس‌های داخلی را کنترل می‌کند. در پروژه‌های کوچک شاید نیازی به استفاده از این ابزارها نباشد، اما در سیستم‌های بزرگ و پیچیده استفاده از آن‌ها باعث می‌شود مدیریت و نگهداری سیستم بسیار راحت‌تر شود.8.      CQRS (Command Query Responsibility Segregation) CQRS یک روش طراحی نرم‌افزار است که در آن عملیات ثبت و تغییر اطلاعات از عملیات نمایش و خواندن اطلاعات جدا می‌شود. در بسیاری از برنامه‌ ها یک بخش هم داده‌ها را ذخیره و ویرایش می‌کند و هم آن‌ها را نمایش می‌دهد، اما در CQRS این دو کار از هم تفکیک می‌شوند. برای مثال در یک سیستم دانشگاهی، ثبت نمره دانشجو نیاز به دقت، قوانین مشخص و بررسی‌ های مختلف دارد، اما دیدن نمرات یا لیست واحدهای ارائه‌ شده باید سریع و ساده باشد. به همین دلیل می‌توان بخش ثبت و تغییر اطلاعات (مثل وارد کردن نمره یا ثبت‌نام دانشجو) را جدا از بخش نمایش اطلاعات طراحی کرد تا هر کدام بهتر و بهینه‌تر کار کنند.این روش می‌تواند سرعت و مقیاس‌پذیری سیستم را افزایش دهد، چون بخش خواندن و بخش نوشتن به صورت مستقل مدیریت و بهینه می‌شوند. البته CQRS برای همه پروژه‌ها مناسب نیست. در پروژه‌های کوچک معمولاً استفاده از آن فقط باعث پیچیده‌تر شدن سیستم می‌شود. همچنین چون اطلاعات از دو مسیر جدا مدیریت می‌شوند، ممکن است گاهی نمایش اطلاعات با کمی تأخیر به‌روزرسانی شود. به نظر من CQRS بیشتر برای سیستم‌های بزرگ و پرکاربرد مفید است؛ جایی که تعداد درخواست‌ها زیاد است و نیازهای بخش خواندن و نوشتن تفاوت زیادی با هم دارند.9.      Event-Driven Architecture (EDA)معماری EDA یعنی اجزای یک سیستم به جای اینکه مستقیم همدیگر را صدا بزنند، با رویدادها با هم ارتباط برقرار می‌کنند. رویداد یعنی یک اتفاق که در سیستم رخ داده؛ مثل اینکه کاربر ثبت‌نام کرد، سفارش ثبت شد یا پرداخت انجام شد. در این روش، یک بخش سیستم این اتفاق را اعلام می‌کند و بقیه بخش‌ها اگر لازم داشته باشند به آن واکنش نشان می‌دهند.برای مثال وقتی یک سفارش ثبت می‌شود، سیستم سفارش فقط اعلام می‌کند که سفارش ثبت شده است. بعد از آن بخش‌های دیگر مثل ارسال ایمیل، مدیریت انبار یا تحلیل داده‌ها، هرکدام جداگانه کار خودشان را انجام می‌دهند. این باعث می‌شود بخش‌های سیستم وابستگی کمتری به هم داشته باشند و راحت‌تر بتوان آن‌ها را تغییر یا گسترش داد.البته این روش همیشه ساده نیست چون دیگر همه چیز پشت سر هم و خطی نیست، فهمیدن اینکه دقیقاً چه اتفاقی در سیستم افتاده سخت‌تر می‌شود. همچنین باید دقت کرد پیام‌ها گم نشوند، دوباره تکرار نشوند و ترتیبشان درست باشد.10. Serverless Architectureمعماری Serverless یعنی اینکه لازم نیست خودت درگیر مدیریت سرورها بشوید سرورها هنوز وجود دارند، اما همه کارهای سختش مثل راه‌اندازی، نگهداری، آپدیت و افزایش ظرفیتشون رو شرکت‌های ابری انجام میدهند.یکی از مزیت‌های مهم این روش اینه که برای کارهایی که گاهی اجرا می‌شن خیلی به‌صرفه‌ست. چون فقط وقتی استفاده می‌کنی هزینه می‌دی و لازم نیست همیشه سرور روشن نگه داری. همچنین سیستم خودش می‌تونه با افزایش درخواست‌ها بزرگ‌تر بشه و نیاز به تنظیم دستی نداره.البته Serverless بی‌نقص نیست. بعضی وقت‌ها اجرای کد با کمی تأخیر شروع می‌شه، محدودیت زمانی برای اجرای هر تابع وجود داره و کنترل روی محیط اجرا کمتره. همچنین پیدا کردن خطاها یا تست کردن برنامه ممکنه سخت‌تر باشه. به طور خلاصه، Serverless برای کارهای سبک، API های ساده یا کارهایی که گاهی اجرا می‌شن خیلی خوبه، اما برای سیستم‌های خیلی سنگین یا پیچیده همیشه بهترین انتخاب نیست.11. API-first Approachرویکرد API-first یعنی قبل از اینکه شروع کنیم کل برنامه را بسازیم اول مشخص می‌کنیم برنامه چطور با بخش‌های دیگر ارتباط می‌گیرد یعنی API را از اول به عنوان بخش اصلی کار در نظر می‌گیریم نه چیزی که آخر کار اضافه شود.در این روش قبل از نوشتن کد مشخص می‌شود چه درخواست‌هایی داریم، چه اطلاعاتی باید بفرستیم و چه جوابی برگردد. حتی چیزهایی مثل خطاها، ورود و خروج داده‌ها و نسخه‌های مختلف API هم از قبل طراحی می‌شوند.این کار باعث می‌شود تیم‌ها راحت‌تر با هم کار کنند مثلاً تیم فرانت‌اند می‌تواند بدون داشتن بک‌اند کامل، با داده‌های فرضی کار کند. تیم بک‌اند هم جداگانه روی پیاده‌سازی کار می‌کند. این موضوع سرعت توسعه را بالا می‌برد و هماهنگی را ساده‌تر می‌کند.یکی دیگر از مزیت‌های API-first این است که طراحی API تمیزتر و بهتر می‌شود، چون از ابتدا با فکر و برنامه‌ریزی ساخته می‌شود، نه اینکه بعداً از روی اجبار به کد اضافه شود. البته این روش نیاز به دقت و هماهنگی دارد. اگر API مدام تغییر کند، بقیه تیم‌ها دچار مشکل می‌شوند. برای همین مستندسازی و مدیریت نسخه‌ها خیلی مهم است. 12. Domain Driven DesignDDD  یعنی طراحی نرم ‌افزار را بر اساس موضوع اصلی کسب‌وکار انجام بدهیم، نه فقط بر اساس کد و تکنولوژی. منظور از دامنه همان حوزه‌ای است که نرم‌افزار برای آن ساخته می‌شود؛ مثل آموزش، بانک، فروشگاه یا بیمه. ایده اصلی این است که بیشتر پیچیدگی نرم‌افزار از فهم درست کارهای واقعی کسب‌وکار می‌آید، نه از خود برنامه‌نویسی.در این روش تلاش می‌شود همه افراد تیم، یعنی برنامه‌نویس‌ها و افراد بیزنسی، از یک زبان مشترک استفاده کنند. مثلاً وقتی می‌گویند سفارش، پرداخت یا مرجوعی، همه دقیقاً یک معنی یکسان از آن داشته باشند و همین مفاهیم هم در کد استفاده شود و این کار باعث می‌شود فهم سیستم ساده ‌تر و اشتباهات کمتر شود.یک نکته مهم دیگر در DDD این است که یک کلمه ممکن است در بخش‌های مختلف سیستم معنی متفاوتی داشته باشد برای همین سیستم به بخش‌های جدا تقسیم می‌شود تا هر بخش معنی خودش را از مفاهیم داشته باشد و همه‌چیز قاطی نشود. به طور کلی، DDD کمک می‌کند نرم‌افزار شبیه دنیای واقعی کسب‌وکار ساخته شود، نه فقط شبیه یک ساختار فنی.13. Hexagonal architectureمعماری شش‌ضلعی یا Hexagonal Architecture یعنی اینکه بخش اصلی برنامه را از چیزهای بیرونی مثل دیتابیس، رابط کاربری یا سرویس‌های دیگر جدا کنیم. ایده اصلی این است که منطق اصلی برنامه که همان قوانین کسب‌وکار است، نباید به هیچ تکنولوژی خاصی وابسته باشد.در این روش، برنامه یک هسته مرکزی دارد که کار اصلی را انجام می‌دهد. اطراف این هسته پورت و آداپتر قرار می‌گیرند که پورت‌ها در واقع مثل یک قرارداد هستند که مشخص می‌کنند برنامه چه ورودی و خروجی‌هایی دارد و آداپترها هم وظیفه دارند این قراردادها را به دنیای واقعی وصل کنند مثلاً یک آداپتر می‌تواند داده‌ها را در دیتابیس ذخیره کند و یک آداپتر دیگر می‌تواند فقط برای تست، اطلاعات را داخل حافظه نگه دارد.مزیت این روش این است که هسته اصلی برنامه دست ‌نخورده باقی می‌ماند و اگر بخواهیم دیتابیس یا فریمورک را عوض کنیم، فقط آداپترها تغییر می‌کنند. این موضوع باعث می‌شود تست کردن برنامه هم راحت‌تر شود، چون می‌توان بدون وابستگی به دیتابیس یا ابزارهای خارجی، منطق اصلی را بررسی کرد.به طور کلی، این معماری می‌گوید بخش مهم برنامه باید مستقل از ابزارها باشد و ابزارها فقط نقش کمک‌کننده داشته باشند، نه اینکه هسته اصلی سیستم را تشکیل دهند. این روش بیشتر برای پروژه‌های متوسط و بزرگ مناسب است، چون در پروژه‌های کوچک ممکن است بیش از حد پیچیده به نظر برسد.14. Event SourcingEvent Sourcing  یعنی به جای اینکه فقط وضعیت فعلی یک سیستم را ذخیره کنیم، همه اتفاق‌هایی که باعث تغییر آن شده‌اند را نگه می‌داریم. برای مثال در یک حساب بانکی، به جای اینکه فقط بگوییم الان موجودی چقدر است، همه تراکنش‌ها را ذخیره می‌کنیم؛ مثل اینکه پول واریز شده، برداشت انجام شده یا کارمزدی کم شده است. بعد اگر بخواهیم موجودی فعلی را بدانیم، همه این اتفاق‌ها را از اول حساب می‌کنیم و به نتیجه می‌رسیم.ایده ساده این است که به جای دیدن فقط نتیجه نهایی، کل مسیر اتفاق‌ها را هم داشته باشیم که این کار کمک می‌کند بفهمیم سیستم دقیقاً چه روندی را طی کرده و در صورت مشکل، راحت ‌تر بتوانیم ریشه آن را پیدا کنیم. همچنین برای بررسی تاریخچه یا گزارش‌گیری خیلی مفید است، مخصوصاً در سیستم‌هایی مثل مالی که جزئیات تغییرات مهم هستند.15. Low-code/No-code platformsپلتفرم‌های Low-code و No-code ابزارهایی هستند که کمک می‌کنند نرم‌افزار را خیلی سریع‌تر و ساده‌تر بسازیم. در Low-code هنوز کمی کدنویسی لازم است، اما بیشتر کارها با ابزارهای آماده و تصویری انجام می‌شود. در No-code حتی نیازی به کدنویسی نیست و افراد معمولی هم می‌توانند با کشیدن و رها کردن اجزا، یک برنامه ساده بسازند.دلیل محبوب شدن این ابزارها این است که خیلی از بخش‌های یک سازمان نیاز به برنامه‌ های ساده دارند، اما همیشه زمان و منابع تیم برنامه‌نویسی کافی نیست. برای همین این ابزارها کمک می‌کنند خود تیم‌های غیر فنی هم بتوانند کارهای ساده‌شان را سریع انجام دهند، بدون اینکه منتظر تیم توسعه بمانند.البته این روش‌ها محدودیت دارند. اگر پروژه پیچیده باشد یا نیاز به کنترل دقیق و عملکرد بالا داشته باشد، این ابزارها کافی نیستند. همچنین اگر بدون نظارت استفاده شوند، ممکن است هر بخش سازمان یک برنامه جدا بسازد و بعداً مدیریت و هماهنگ کردن آن‌ها سخت شود.16. Business Process Management Systems (BPMS)BPMS یا سیستم مدیریت فرایند کسب‌ و کار ابزاری است که کمک می‌کند کارهای داخل یک سازمان به شکل منظم ‌تر و قابل‌ پیگیری انجام شوند. منظور از فرایند، یک سری کار پشت سر هم است که برای رسیدن به یک هدف انجام می‌شود؛ مثل استخدام یک کارمند، بررسی درخواست وام یا تأیید مرخصی. در این سیستم، اول کل فرایند مشخص و طراحی می‌شود یعنی گفته می‌شود چه مراحلی دارد، چه کسانی در هر مرحله نقش دارند و تصمیم‌ها بر چه اساسی گرفته می‌شود. بعد از آن، سیستم این فرایند را اجرا می‌کند و کارها را مرحله به مرحله جلو می‌برد. مثلاً یک درخواست را به فرد درست ارسال می‌کند، زمان انجام کار را ثبت می‌کند و اگر کاری دیر شود، هشدار می‌دهد.مزیت اصلی BPMS این است که همه چیز شفاف می‌شود و مدیر می‌تواند ببیند هر کار در چه مرحله‌ای است و اگر مشکلی وجود دارد، آن را راحت‌تر پیدا کند اما اگر خود فرایند از اول درست طراحی نشده باشد، استفاده از این سیستم فقط باعث می‌شود همان مشکلات سریع‌تر و منظم‌تر تکرار شوند.17. Message Queue (such as Kafka and RabbitMQ)Message Queue  یا صف پیام یعنی یک روش برای اینکه بخش‌های مختلف یک سیستم بدون اینکه مستقیم منتظر هم بمانند با هم کار کنند.در حالت معمول اگر یک بخش بخواهد کاری انجام دهد، باید صبر کند بخش دیگر جواب بدهد. اما در صف پیام اینطور نیست. یک بخش پیام را داخل یک صف می‌گذارد و بعداً بخش دیگر آن را برمی‌دارد و انجام می‌دهد. این باعث می‌شود سیستم سریع‌تر و منظم‌تر کار کند و بخش‌ها وابسته به هم نباشند.ابزارهایی مثل RabbitMQ و Kafka برای این کار استفاده می‌شوند. RabbitMQ بیشتر برای ارسال و دریافت پیام‌ های معمولی استفاده می‌شود، اما Kafka برای حجم خیلی زیاد داده و رویدادهای پشت سر هم مناسب‌تر است.البته استفاده از صف پیام همیشه هم ساده نیست و باید مراقب باشیم پیام ‌ها دوبار پردازش نشوند، ترتیبشان به هم نریزد و اگر خطایی رخ داد سیستم بتواند دوباره تلاش کند. با این حال این روش در سیستم‌های بزرگ خیلی مفید است چون باعث می‌شود سیستم قابل‌اعتمادتر و مقیاس‌پذیرتر باشد.18. Containers (eg., Docker) and Container orchestration (e.g.,  Kubernetes)کانتینر یعنی یک جور بسته‌بندی کردن برنامه به همراه همه چیزهایی که لازم دارد تا اجرا شود. مثلاً اگر یک برنامه برای اجرا به یک نسخه خاص از  Node.js، چند کتابخانه و تنظیمات مشخص نیاز داشته باشد، همه این‌ها داخل یک بسته قرار می‌گیرند تا برنامه در هر سیستمی تقریباً به یک شکل اجرا شود.ابزار داکر یکی از معروف‌ترین ابزارها برای ساخت و اجرای این کانتینرها است و مزیت مهم این روش این است که مشکل معروف روی سیستم من کار می‌کند ولی روی سیستم تو نه تا حد زیادی حل می‌شود، چون همه چیز داخل یک بسته ثابت قرار دارد.اما وقتی تعداد کانتینرها زیاد می‌شود، مدیریت آن‌ها سخت می‌شود مثلاً باید مشخص شود هر کانتینر کجا اجرا شود، اگر از کار افتاد دوباره بالا بیاید، اگر فشار زیاد شد چند نسخه جدید ساخته شود و ارتباط بین آن‌ها چطور باشد.برای حل این مشکل از ابزارهایی مثل کوبرنتیز استفاده می‌شود که کمک می‌کند کانتینرها به صورت خودکار مدیریت شوند، مقیاس پیدا کنند و در صورت خرابی دوباره اجرا شوند.19. Multi-Tenancy Architectureمعماری Multi-Tenancy یعنی اینکه یک نرم‌ افزار واحد به چند مشتری یا سازمان مختلف سرویس بدهد، اما هر کدام از آن‌ها داده‌ ها و اطلاعات جداگانه خودشان را داشته باشند که به هر مشتری در این مدل tenant گفته می‌شود.برای مثال فرض کنید یک سامانه آموزشی توسط چند دانشگاه مختلف استفاده می‌شود. همه دانشگاه‌ها از یک نرم‌افزار مشترک استفاده می‌کنند، اما هر دانشگاه فقط به اطلاعات دانشجویان، اساتید، دروس و نمرات خودش دسترسی دارد و نمی‌تواند اطلاعات دانشگاه‌های دیگر را مشاهده کند.مزیت این روش این است که هزینه نگهداری و توسعه نرم‌افزار کمتر می‌شود، چون به جای ساخت و مدیریت چند سامانه جداگانه، فقط یک سیستم مشترک وجود دارد. همچنین به‌روزرسانی‌ها و قابلیت‌های جدید یک‌بار روی سیستم اعمال می‌شوند و همه دانشگاه‌ها از آن بهره‌مند می‌شوند. البته مهم‌ترین چالش این معماری حفظ جداسازی اطلاعات است و سیستم باید طوری طراحی شود که اطلاعات هر دانشگاه کاملا مستقل و امن باشد و به هیچ عنوان با اطلاعات دانشگاه‌های دیگر مخلوط نشود.20. Data MigrationData Migration  یعنی انتقال اطلاعات از یک سیستم یا پایگاه داده به یک سیستم جدید. این کار معمولاً زمانی انجام می‌شود که یک سازمان بخواهد نرم‌افزار خود را عوض کند، دیتابیس را ارتقا دهد یا از یک سیستم قدیمی به سیستم جدید منتقل شود.برای مثال، فرض کنید یک دانشگاه سال‌ها از یک سامانه آموزشی قدیمی استفاده کرده و حالا می‌خواهد سامانه جدیدی راه‌اندازی کند. در این حالت اطلاعات دانشجویان، اساتید، نمرات و انتخاب واحدها باید از سیستم قدیمی به سیستم جدید منتقل شوند. مهم‌ترین بخش مهاجرت داده این است که قبل از شروع، همه چیز به‌خوبی برنامه‌ریزی شود، باید مشخص شود چه اطلاعاتی منتقل می‌شوند، اطلاعات تکراری یا اشتباه چگونه اصلاح می‌شوند و بعد از انتقال چطور مطمئن شویم همه داده‌ها درست منتقل شده‌اند.گاهی برای انجام این کار، سیستم قدیمی برای مدتی از دسترس خارج می‌شود تا انتقال انجام شود اما در بعضی موارد، سیستم قدیمی و جدید مدتی همزمان کار می‌کنند تا اطلاعات به‌تدریج منتقل شوند و کاربران کمتر دچار مشکل شوند.به طور کلی Data Migration یعنی جا به ‌جایی امن و صحیح اطلاعات از یک سیستم به سیستم دیگر و چون داده‌ها بسیار ارزشمند هستند، اگر این کار به‌درستی انجام نشود ممکن است اطلاعات از بین بروند یا مشکلات زیادی برای کاربران ایجاد شود.لیست منابعPrinciples of Chaos EngineeringSam Newman Articles &amp; PublicationsMartin Fowler ArticlesAWS Architecture CenterAzure Architecture CenterOpenAPI InitiativeKubernetes DocumentationHashiCorp Developer DocumentationACM Digital Library &amp; arXiv SurveysOMG BPMN Specificationصحبت با chatgpt , gemini</description><category>مهدی مهدی پور</category><author>مهدی مهدی پور</author><pubDate>Mon, 01 Jun 2026 18:05:40 +0330</pubDate></item></channel></rss>