<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های Maedeh Zarei</title><link>https://virgool.ir/feed/@MaedehZarei</link><description></description><language>fa</language><pubDate>2026-11-10 21:36:10</pubDate><image><url>https://files.virgool.ir/upload/users/4887053/avatar/oyzmAD.jpg</url><title>Maedeh Zarei</title><link>https://virgool.ir/@MaedehZarei</link></image><item><title>شرح کامل پروژه درس معماری نرم افزار، سامانهٔ اطلاعات و خدمات بیمارستانی HISS</title><link>https://virgool.ir/@MaedehZarei/پروژه-درس-معماری-نرم-افزار-سامانهٔ-اطلاعات-و-خدمات-بیمارستانی-hiss-nnoswoz4dnwz</link><description>وقتی صحبت از یک سامانهٔ بیمارستانی میشود، اولین تصویری که معمولاً به ذهن میرسد مجموعهای از قابلیتهای مختلف مانند ثبت بیمار، جستوجوی پزشک، نوبتدهی، پروندهٔ پزشکی و صدور صورتحساب است. اما در یک پروژهٔ معماری نرمافزار، پرسش اصلی فقط این نیست که سیستم چه کارهایی انجام میدهد؛ پرسش مهمتر این است که این سیستم چرا باید به این شکل طراحی شود و این طراحی چگونه کیفیتهای مورد انتظار را در شرایط واقعی تضمین میکند؟پروژهٔ HISS یا Hospital Information and Service System با همین نگاه طراحی شده است؛ یک نمونهٔ کوچک اما معماریمحور از سامانهٔ اطلاعات و خدمات بیمارستانی که هدف آن، بیش از آن که شبیهسازی کامل یک بیمارستان واقعی باشد، نمایش تصمیمهای معماری، trade-offها، سناریوهای کیفیتی، جداسازی مسئولیتها، ارتباط رویدادمحور و یک حلقهٔ خودسازگار سبک است.در این پروژه تلاش شده است میان سادگی لازم برای یک نمونهٔ دانشجویی و بررسی متعادل معماری برقرار شود. بنابراین سیستم عمداً به یک زیرساخت توزیعشدهٔ سنگین تبدیل نشده و در عوض، معماری آن بر پایهٔ یک Modular Monolith، لایهبندی داخلی هر ماژول، ارتباط Event-Driven درونبرنامهای، الگوی Adapter برای یکپارچهسازی و یک حلقهٔ MAPE-K مبتنی بر Rule بنا شده است.HISS — Hospital Information &amp; Service Systemمسئله و زمینهٔ کسب و کارHISS تصویری سادهشده از گردش کار روزمرهٔ یک بیمارستان ارائه میدهد. در این محیط، بیمار ثبت میشود، پزشک جستوجو میشود، برای بیمار نوبت ثبت میشود، اطلاعات پایهٔ پزشکی در دسترس قرار میگیرد، صورتحساب ساخته میشود و در صورت نیاز، سیستم با سرویسهایی مانند بیمه، داروخانه یا آزمایشگاه تعامل میکند.چهار نقش اصلی در سیستم وجود دارند:. بیمار. پزشک. پذیرش. مدیر سیستمبیمار میتواند پزشک را جستوجو کند، نوبت بگیرد و اطلاعات مجاز مربوط به خود را مشاهده یا ویرایش کند. پذیرش علاوه بر ثبت بیمار، در فرآیندهای نوبتدهی و صورتحساب نقش دارد. پزشک برنامهٔ کاری و بیماران مرتبط با خود را مشاهده میکند و مدیر، بیشتر با جنبههای عملیاتی، پایش وضعیت سیستم، رخدادهای سازگاری و درخواستهای مدیریتی سر و کار دارد.از طرف دیگر، سه سیستم بیرونی که در یک بیمارستان واقعی میتوانند وجود داشته باشند، در این پروژه به صورت Mock Adapter مدل شدهاند:. سامانهٔ بیمه. سامانهٔ داروخانه. سامانهٔ آزمایشگاهنکتهٔ معماری اینجا مهم است. هدف پروژه شبیهسازی شبکه و API واقعی این سرویسها نیست؛ هدف این است که مرز یکپارچهسازی بهشکل واقعی طراحی شود تا در آینده بتوان پیادهسازی Mock را با یک سرویس واقعی جایگزین کرد.محدودهٔ سیستمقابلیتهای اصلی HISS شامل این موارد است:. احراز هویت و مدیریت کاربران. مدیریت اطلاعات بیمار. نمایش خلاصهٔ پروندهٔ پزشکی. جستوجوی پزشک. مشاهدهٔ زمانهای قابل رزرو. ثبت، لغو و تغییر نوبت. مدیریت اولویت نوبتهای اضطراری. ایجاد فاکتور. محاسبهٔ هزینه و وضعیت بیمه. اعلانهای سیستم. اتصال Mock به بیمه، داروخانه و آزمایشگاه. داشبورد مدیریتی و پایش وضعیت سیستم. ثبت رخدادهای عملیاتی و امنیتی. مدیریت درخواستهای تغییر برخی اطلاعات حساس پروفایلدر مقابل، پروژه عمداً وارد حوزههایی مانند Telemedicine کامل، پیچیدگی کامل EMR/EHR، پرداخت واقعی، انبار دارو، LIS واقعی، PACS، فرآیند کامل اورژانس و زیرسیستمهای اداری بیمارستان نمیشود. این محدودسازی بخشی از تصمیم معماری پروژه است و نه یک کمبود تصادفی. هدف آن است که ظرفیت پروژه صرف نمایش استدلال معماری شود، نه پیادهسازی زیرساختی که از مسئلهٔ اصلی دور شود.از Functionality تا Quality Attributeیکی از مهمترین تفاوتهای دیدگاه معماری نرمافزار با توسعهٔ صرفاً قابلیتمحور، توجه به Quality Attributeها است.در این پروژه، کیفیتها بهصورت صفتهای مبهم مانند &#34;سیستم سریع باشد&#34; یا &#34;سیستم امن باشد&#34; در نظر گرفته نشدهاند.برای هر کیفیت، باید بتوان مشخص کرد:. چه چیزی را اندازه میگیریم؟. در چه شرایطی؟. با چه هدفی؟. اگر سیستم با یک محرک خاص مواجه شد، چه واکنشی باید نشان دهد؟این نگاه با الگوی سناریوهای Quality Attribute که در درس معماری نرمافزار مطرح میشود همراستا است. در پروژه، سناریوها به اجزایی مانند منبع محرک، خود محرک، محیط، Artifact، پاسخ و معیار پاسخ شکسته شدهاند.اولویت Quality Attributeهااز همان ابتدا برای کیفیتهای سیستم یک ترتیب اولویت مشخص در نظر گرفته شد:1. Availability2. Performance3. Security4. Integrability5. Modern Architectural Topics6. Testability7. Maintainability / Modifiabilityاین ترتیب صرفاً یک فهرست نیست. مهمترین کاربرد آن زمانی مشخص میشود که دو کیفیت با یکدیگر تعارض دارند.برای مثال، استفاده از bcrypt هزینهٔ محاسباتی بیشتری نسبت به روشهای سادهتر دارد، اما به دلیل اهمیت Security قابل توجیه است. از طرف دیگر، در مسیرهای پرتکرار مانند جستوجو و نوبتدهی، Performance اهمیت بیشتری پیدا میکند. به بیان دیگر، Quality Attributeها رایگان نیستند و هر تصمیم معماری روی چند کیفیت اثر میگذارد. بنابراین معماری به یک اولویت صریح نیاز دارد تا هنگام تعارض بتواند تصمیم بگیرد کدام کیفیت در آن پروژه مهمتر است.معماری انتخابشدهمعماری HISS از ترکیب چند ایده شکل گرفته است:Modular Monolith + Layered Architecture + Event-Driven Communication + Rule-Based Self-Adaptationدر نگاه اول ممکن است این ترکیب متناقض به نظر برسد؛ چون Event-Driven و MAPE-K گاهی با سیستمهای توزیعشده، Microserviceها و زیرساختهای پیچیده تداعی میشوند. اما در این پروژه این مفاهیم در اندازهٔ یک برنامهٔ تکفرآیندی پیادهسازی شدهاند.چرا Modular Monolith؟HISS یک برنامهٔ قابل استقرار دارد، اما داخل آن به چندین ماژول مستقل تقسیم شده است.ماژولهای اصلی شامل این بخشها هستند:. Authentication. Patients. Doctors. Appointments. Billing. Notifications. Integrations. Profile. Tickets. Events. Adaptation. Auditاین ساختار اجازه میدهد سیستم از نظر فیزیکی ساده باقی بماند، اما از نظر منطقی مانند مجموعهای از زیرسیستمهای مستقل سازماندهی شود. در ارائهٔ پروژه، این ساختار در قالب دوازده ماژول و یک پردازش اصلی FastAPI مستند شده است.در نتیجه، یک ماژول جدید لزوماً نباید به فایلها و پوشههای مشترک همهٔ ماژولهای دیگر دست بزند.این انتخاب آگاهانه در مقابل Microservices قرار گرفته است. تبدیل دوازده ماژول داخلی به سرویسهای شبکهای، مسئلههای دیگری مانند Service Discovery، Serialization، Failureهای شبکه، Partial Failure و مدیریت چند Process را وارد پروژه میکرد؛ مسائلی که برای این نمونهٔ دانشگاهی نه تنها ضروری نبودند، بلکه تمرکز را از بحث معماری مورد نظر دور میکردند.Fig. 3 — c4 model,container diagram. &#34;Container&#34; is the C4 sense (an independently runnable unit) — not Docker. There is deliberately exactly one running process (ADR 008).Fig. 4 — c4 model, component diagram (relationship list trimmed for legibility — the file on disk lists every module&#39;s core dependency too). No Code-level (4th) C4 diagram is maintained by hand, per the course&#39;s own guidance.چهار لایه، اما درون هر ماژولیکی از تصمیمهای مهم HISS این است که لایهبندی بهشکل یک ساختار سراسری مانند api/, service/, domain/ و repository/ در نظر گرفته نشده است.در عوض، هر ماژول تا حد امکان ساختار لایهای خودش را دارد:app/appointments/api.pyservice.pydomain.pyrepository.pymodels.pyدر نتیجه، چهار لایهٔ مفهومی عبارتاند از:Presentationمسئول Routeها، شکل ورودی و خروجی درخواستها و تعامل با UI است.Applicationمنطق Use Case، orchestration، تراکنشها و کنترل دسترسی در این لایه قرار دارد.Domainقوانین کسبوکار خالص، بدون دسترسی مستقیم به I/O، در این بخش قرار میگیرند؛ البته فقط در ماژولهایی که واقعاً به منطق دامنهٔ غنی نیاز دارند.Infrastructureمسئول Persistence و تعامل با SQLAlchemy و سایر جزئیات فنی است.این موضوع با ایدهٔ Clean Architecture در جداسازی وابستگیها و حفاظت از منطق کسبوکار همجهت است، اما پروژه یک پیادهسازی کاملاً کلاسیک و یکسان از آن ارائه نمیدهد. تصمیم عملی پروژه این بوده که لایهها درون Feature Moduleها قرار بگیرند.Fig. 5 — the stack repeated identically in auth/, patients/, appointments/, ... Only appointments and billing have a real domain.py — other modules&#39; logic is thin enough to live directly in service.py, which is itself a documented, deliberate choice, not an inconsistency.چرا Domain بهصورت Shared Package نیست؟در پروژه میتوانستیم یک پوشهٔ مشترک مانند app/domain/ داشته باشیم؛ اما چنین ساختاری باعث میشد Featureهای مختلف مرتباً وارد یک فضای مشترک شوند. در یک Modular Monolith، این موضوع میتواند Coupling سازمانی ایجاد کند؛ حتی اگر Coupling فنی ظاهراً کم باشد.در HISS، با قرار گرفتن لایهها داخل هر ماژول، یک Feature را میتوان تقریباً از ابتدا تا انتها در یک مکان دنبال کرد.هزینهٔ این تصمیم مقداری تکرار در Serviceها است، اما با توجه به اینکه Maintainability پایینترین اولویت پروژه تعیین شده، این Trade-off به نفع خوانایی محلی و کاهش وابستگی بین ماژولها پذیرفته شده است.حتی این اصل در Controllerها نیز قابل مشاهده و قابل بررسی است: api.py صرفاً کار تبدیل Request و Response را انجام میدهد و Query مربوط به SQLAlchemy یا Business Rule در آن قرار نگرفته است.نمای C4 و تقسیمبندی سیستمبرای توضیح معماری از Viewهای C4 نیز استفاده شده است.در سطح Container، عمداً تنها یک واحد اجرایی واقعی وجود دارد؛ همان برنامهٔ FastAPI. در اینجا Container به معنای C4 است و نه Docker Container. درون این Application، Componentهای اصلی شامل Authentication، Patient، Doctor، Appointment، Billing، Notification، Integration Adapter، Profile، Tickets، Event Bus، Adaptation، Audit و Core هستند.ارتباط آنها نیز به شکل مشخصی تعریف شده است. برای مثال:. Appointment رویداد منتشر میکند.. Notification رویداد را مصرف میکند.. Audit رویدادها را ثبت میکند.. Billing از Adapter facade استفاده میکند.. Integration timeoutها را به Adaptation گزارش میدهد.. Authentication failureها نیز ورودی حلقهٔ Adaptation هستند.این Viewها کمک میکنند تفاوت میان «ساختار استقرار» و «ساختار منطقی» روشن بماند.مدل داده و موجودیتهای اصلیمدل دادهٔ HISS نیز با تمرکز بر دامنهٔ اصلی سیستم طراحی شده است.موجودیتهای اصلی شامل موارد زیر هستند:. User. Role. Patient. Doctor. DoctorSpecialization. DoctorAvailability. Appointment. Invoice. Notification. Ticket. AuditLog. AdaptationRule. AdaptationEvent. MockAdapterStateبرای نمونه، Appointment به Patient و Doctor وابسته است و میتواند Invoice متناظر داشته باشد. Invoice نیز وضعیت پرداخت و وضعیت بررسی بیمه را نگه میدارد. همچنین AdaptationRule و AdaptationEvent بخشی از Model مربوط به خودسازگاری سیستم هستند.نکتهٔ جالب این است که Profile بهعنوان یک Table مستقل وجود ندارد. این بخش بیشتر یک Use Case و orchestration روی موجودیتهای User، Patient و Doctor است و به همین دلیل ایجاد یک موجودیت جدید صرفاً برای نامگذاری Profile ضروری تشخیص داده نشده است.Fig. 6 — domain model. Profile is deliberately absent as a table: app/profile/ has no models.py — it orchestrates User/Patient/Doctor directly.patientdoctorreceptionistadminارتباط Event-Driven درون برنامهیکی از مهمترین ایدههای پروژه، Event-Driven Communication است.برای این کار یک Event Bus بسیار سبک درونپردازشی وجود دارد که از الگوی Publish/Subscribe استفاده میکند.برای مثال، پس از ثبت موفق نوبت:AppointmentService &gt; publish(AppointmentBooked) &gt; Notification &gt; Auditدر نتیجه Appointment Module لازم نیست Notification یا Audit را مستقیماً Import کند.این موضوع یک Decoupling واقعی ایجاد میکند. در Sequence Diagram پروژه، پس از انتشار AppointmentBooked تمام واکنشهای بعدی از طریق Event Bus انجام میشوند و Service نوبتدهی مستقیماً با Notification یا Audit صحبت نمیکند.مزیت مهم این کار برای آینده این است که اگر مثلاً کانال SMS اضافه شود، لازم نیست منطق Appointment تغییر کند. کافی است یک Handler جدید برای Event مورد نظر اضافه شود.به همین دلیل، Event-Driven Design در این پروژه فقط یک موضوع مدرن نیست؛ یک ابزار مستقیم برای Integrability و Modifiability است.Adapter و Integrabilityیک بیمارستان واقعی وابسته به سیستمهای بیرونی متعددی است. در این پروژهٔ دانشجویی، اتصال واقعی به چنین سرویسهایی عملی و حتی ضروری نیست. اما حذف کامل مرز Integration هم از نظر معماری منطقی نبود.راهحل HISS، استفاده از یک BaseAdapter است.منطق مصرفکننده به یک Interface مشخص وابسته میماند و جزئیات سرویس خارجی پشت Adapter قرار میگیرد.بنابراین:Billing → BaseAdapter → Mock Insuranceو در نسخهٔ آینده میتواند به:Billing → BaseAdapter → Real Insurance APIتبدیل شود.این دقیقاً همان نقطهای است که معماری از قابل اجرا بودن به قابل توسعه بودن میرسد. حتی اگر سرویس واقعی هرگز ساخته نشود، مرز آن از ابتدا در معماری مشخص شده است.گردش کامل یک نوبتیکی از مهمترین Use Caseهای سیستم، رزرو نوبت است.گردش کلی به شکل زیر است:ورود کاربر↓جستوجوی پزشک↓انتخاب زمان↓بررسی قوانین رزرو↓ایجاد Appointment↓بررسی صف و وضعیت سیستم↓بررسی بیمه↓ایجاد Invoice در صورت نیاز↓ثبت Audit↓انتشار AppointmentBooked↓Notification↓ثبت رویدادهای مرتبطاما در این فرآیند چند Gate معماری نیز وجود دارد.برای مثال، اگر سیستم وارد حالت degraded_read_only شده باشد، درخواستهای غیراضطراری ممکن است با خطای 503 رد شوند، در حالی که نوبت اضطراری همچنان مجاز باقی بماند. همچنین زمان گذشته یا تداخل زمانی یک نوبت با نوبت قبلی، قبل از ایجاد Appointment بررسی میشود.این مثال نشان میدهد که Quality Attributeها صرفاً در یک سند نوشته نشدهاند؛ بلکه مستقیماً وارد Flow اصلی سیستم شدهاند.Performance Scenario 3 — search by name/specialization, target &lt;2s. Single indexed query, doctors/repository.py.Performance Scenario 4 — booking completes, target &lt;3s. Naive-UTC slot comparison avoids an aware/naive datetime bug this project hit once.Three notifications, three different domain events, same in-process bus — proof the fan-out actually ran, not just that it compiles.Availability؛ مهمترین کیفیت سیستماولین Quality Attribute در این پروژه Availability است.در یک سامانهٔ بیمارستانی، شکست یک زیرسیستم نباید الزاماً به معنای شکست کل فرآیند باشد. بنابراین، HISS بهجای طراحی برای همهچیز یا هیچچیز، از Graceful Degradation استفاده میکند.سناریوی نمونهفرض کنید سرویس بررسی بیمه از دسترس خارج شود.یک معماری ساده ممکن است چنین رفتاری داشته باشد:Insurance timeout↓Exception↓Booking failedاما HISS تلاش میکند چنین رفتاری داشته باشد:Insurance timeout↓AdapterResult(deferred=True)↓Insurance = DEFERRED↓Billing continues↓Core workflow remains availableدر این طراحی، شکست Adapter به یک Result معنادار تبدیل میشود، نه یک Exception خام. در نتیجه Billing مجبور میشود آگاهانه تصمیم بگیرد با حالت Deferred چه کند. این رفتار باعث میشود اختلال بیمه، کل فرآیند نوبتدهی و صورتحساب را از کار نیندازد.در واقع، در این پروژه Availability از طریق Redundancy چند سرور تأمین نمیشود؛ چون سیستم اصلاً معماری چندسروری ندارد. Availability با کاهش دامنهٔ اثر Failure و ادامهٔ سرویسهای حیاتی محقق میشود./ui/admin — Mock adapters/ui/invoices/1app/integrations/ - base.pyBaseAdapter.call()Performance و مدیریت بارQuality Attribute دوم Performance است.دو سناریوی مشخص برای Performance تعریف شدهاند:جستوجوی پزشکدرخواست جستوجوی پزشک بر اساس نام یا تخصص باید معمولاً در کمتر از دو ثانیه پاسخ دهد.ثبت نوبتدر شرایط بار عادی، ثبت نوبت باید معمولاً کمتر از سه ثانیه طول بکشد.این اهداف در قالب Testهای جداگانه نیز بررسی شدهاند.علاوه بر کاهش Latency در مسیرهای اصلی، پروژه از Performance در کنار Availability نیز استفاده میکند. برای مثال، وقتی Queue بیش از مقدار مشخصی رشد کند، سیستم وارد حالت اولویتدهی به نوبتهای اضطراری میشود.در نتیجه بهجای اینکه صرفاً تعداد بیشتری از درخواستها را بپذیرد، تلاش میکند در شرایط فشار، درخواست مهمتر را زودتر سرویس دهد./ui/profile/ui/patientMAPE-K؛ خودسازگاری بدون هوش مصنوعییکی از بخشهای معماری که پروژه را از یک CRUD ساده جدا میکند، وجود یک حلقهٔ MAPE-K است:MonitorAnalyzePlanExecuteKnowledgeاین حلقه در HISS کاملاً Rule-Based است و از Machine Learning استفاده نمیکند.دلیل این انتخاب این است که در یک پروژه، مهم است تصمیم سیستم قابل مشاهده و قابل توضیح باشد. وقتی Rule مشخص است، میتوان دقیقاً گفت: &#34;اگر این وضعیت رخ داد، این سیاست اجرا میشود&#34;.در پروژه حتی یک Thread پسزمینهٔ دائمی برای Poll کردن وضعیت وجود ندارد. چون اغلب Signalهای مورد نیاز، مانند Login Failure، Queue Length، Adapter Timeout و Latency، همان لحظهٔ پردازش Request اتفاق میافتند. بنابراین MAPE-K به صورت Synchronous و در همان مسیر اجرا میشود.MonitorMonitor وضعیتهایی مانند این موارد را میگیرد:تعداد درخواستهای در حال پردازشطول صف نوبتمیانگین Latencyتعداد Login FailureهاTimeoutهای Adapterتعداد Notificationهای معوقAnalyzeAnalyze وضعیت فعلی را با Thresholdهای از پیش تعریفشده مقایسه میکند.مثلاً:queue_length &gt; 15یا:failed_logins &gt;= 5Planپس از شناسایی Condition، یک Policy انتخاب میشود.ExecutePolicy انتخابشده روی وضعیت Runtime اعمال میشود.KnowledgeKnowledge Base شامل Ruleها، Thresholdها، Policyها و وضعیت سازگاری است.در HISS این Knowledge Base عمداً پیچیده نشده و به صورت Ruleهای ساده و محلی نگهداری میشود.Ruleهای واقعی سیستمچند Rule مهم پروژه عبارتاند از:. QUEUE_OVERLOAD طول صف بیشتر از ۱۵ ENABLE_EMERGENCY_PRIORITY انتقال نوبتهای اضطراری به ابتدای صف. HIGH_LOAD بیش از ۲۵ درخواست در حال پردازش ENABLE_EMERGENCY_PRIORITY افزایش اولویت درخواستهای بحرانی. HIGH_LATENCY میانگین Latency بیشتر از ۸۰۰ms DEGRADE_READ_ONLY محدود کردن Writeهای غیراضطراری. AUTH_BRUTE_FORCE حداقل ۵ Login ناموفق در ۵ دقیقه RATE_LIMIT_LOGIN کاهش یا توقف موقت Login. ADAPTER_DOWN حداقل ۳ Timeout متوالی ROUTE_TO_FALLBACK عبور از مسیر اصلی و ورود به حالت Deferred. NOTIFICATION_BACKLOG بیشتر از ۵۰ اعلان خواندهنشده DELAY_NONCRITICAL_OPS تعویق عملیات غیرضروریاین Ruleها نمونهای از یک Self-Adaptive System بسیار سبک هستند. سیستم رفتار خود را با توجه به وضعیت Runtime تغییر میدهد، اما این تغییر Behavior کاملاً قابل توضیح است.Fig. 9 — the loop has five parts, not four: Knowledge is the shared object every other stage reads or writes (AdaptationRule/AdaptationEvent tables for durable history, the in-memory AdaptationState singleton for live counters).Adaptation Rulesapp/adaptation/monitor.pyLive state exposed at GET /admin/dashboard — the Monitor&#39;s raw observations, human-readable.The knowledge base (six rules) and a real firing.Security؛ فراتر از LoginSecurity در HISS فقط به Login محدود نشده است.سه سطح مهم در اینجا وجود دارد:Authenticationابتدا باید مشخص شود کاربر واقعاً چه کسی است.برای این کار:. Username &amp; Password. Password Hashing. JWT. FastAPI Dependencyاستفاده شده است.همین Dependency هم API و هم رابط Server-Rendered را پوشش میدهد. در API، Token از Authorization Header گرفته میشود و در UI، همان Token از HttpOnly Cookie خوانده میشود. سپس require_role() سطح Authorization را اعمال میکند.Authorizationدانستن هویت کاربر کافی نیست.برای مثال، اینکه فرد Doctor است لزوماً به معنی آن نیست که بتواند پروندهٔ هر بیمار را ببیند. به همین دلیل، علاوه بر RBAC، Object-Level Authorization نیز وجود دارد.مثلاً پزشک فقط باید بتواند پروندهٔ بیمارانی را ببیند که ارتباط کاری مجاز با آنها دارد. بیمار نیز فقط باید به پروندهٔ خودش دسترسی داشته باشد.Audit &amp; Traceabilityبرای عملیات حساس، Audit Log نیز وجود دارد.این Logها در جدول audit_logs ذخیره میشوند و فقط یک فایل Log متنی موقتی نیستند. در نتیجه عملیات مهم قابل Query و بررسی باقی میمانند.127.0.0.1:8000/ui/loginapp/core/deps.py - get_current_user()سناریوی امنیتی Brute Forceیکی از سناریوهای مشخص Security، تکرار Login ناموفق است.اگر در یک بازهٔ کوتاه چند تلاش ناموفق انجام شود:Failed logins↓Monitor↓Analyze↓AUTH_BRUTE_FORCE↓RATE_LIMIT_LOGIN↓Lock / DelayCooldown نیز بعد از نقضهای بعدی افزایش پیدا میکند.این نکته جالب است که یک Tactic با ریشهٔ Performance/Availability در اینجا برای Security استفاده شده است. Rate Limiting فقط یک ابزار امنیتی نیست؛ در واقع با محدود کردن مصرف منابع، میتواند روی Performance نیز اثر بگذارد. پروژه عمداً این تعامل میان Quality Attributeها را نشان میدهد. همچنین Check مربوط به Lockout قبل از محاسبهٔ Password Hash انجام میشود تا حتی در حالت Lock شده، هزینهٔ اضافی bcrypt پرداخت نشود.Fig. 10 — reproduced verbatim against the running server: five curl requests with a wrong password, then a sixth with the correct password — still rejected with 429.یک تصمیم امنیتی دیگر؛ تغییر اطلاعات هویتیدر طول توسعه، یک سؤال معماری واقعی ایجاد شد که آیا کاربر باید بتواند تمام اطلاعات پروفایل خود را مستقیماً ویرایش کند؟برای بعضی فیلدها پاسخ مثبت است و برای برخی دیگر پاسخ منفی؛ در نتیجه فرآیند Ticket ایجاد شد.برای نمونه، تغییر برخی فیلدهای حساس مانند نام، Username یا شمارهٔ تلفن ابتدا به یک Ticket تبدیل میشود:User↓Profile Change Request↓Ticket↓TicketCreated↓Admin Review├── Approve└── Reject↓TicketResolvedاین تصمیم بهجای اینکه منطق بررسی تغییرات در چند جای مختلف تکرار شود، از یک منبع مشترک برای تعیین فیلدهای محدودشده استفاده میکند./ui/profile/edit/ui/admin/tickets/ui/admin/ticketsOWASP password policyسناریوهای رسمی Quality Attributeپروژه برای QAهای اصلی، هشت سناریوی مشخص تعریف و به Code و Test متناظر متصل کرده است:سناریوی ۱ — Availabilityمحرک: Timeout سرویس بیمه هنگام نوبتدهی یا صورتحسابپاسخ: سیستم وارد حالت Deferred میشود و جریان اصلی ادامه پیدا میکند.معیار: سیستم Crash نکند و Booking/Billing امکان ادامه داشته باشد.سناریوی ۲ — Availabilityمحرک: افزایش شدید بار و تعداد زیاد درخواستهای نوبتپاسخ: سیستم درخواستهای اضطراری را در اولویت قرار دهد.معیار: فرآیند اصلی نوبتدهی همچنان قابل استفاده باشد.سناریوی ۳ — Performanceمحرک: جستوجوی پزشکمعیار: معمولاً کمتر از دو ثانیه.سناریوی ۴ — Performanceمحرک: ثبت نوبتمعیار: معمولاً کمتر از سه ثانیه.سناریوی ۵ — Securityمحرک: تلاش بیمار برای دسترسی به پروندهٔ بیمار دیگرپاسخ: دسترسی رد و رخداد ثبت شود.معیار: هیچ دادهٔ خصوصی افشا نشود.سناریوی ۶ — Securityمحرک: چند Login ناموفقپاسخ: سیستم Login را محدود یا موقتاً مسدود کند.سناریوی ۷ — Integrabilityمحرک: از دسترس خارج شدن Adapter بیمهپاسخ: استفاده از Fallback یا Pending/Deferred State.معیار: جریان اصلی همچنان فعال باشد.سناریوی ۸ — Testabilityمحرک: اجرای تست قواعد نوبتدهیپاسخ: تست بدون UI یا Database اجرا شود.معیار: Core Business Logic مستقل و قابل آزمون باشد.این نکته اهمیت دارد که سناریوها صرفاً در گزارش نوشته نشدهاند؛ برای آنها Test و Code مشخص معرفی شده است.Quality Attribute ScenariosTestability و MaintainabilityTestability در این پروژه، نتیجهٔ مستقیم مرزبندی معماری است.برای Unit Test، منطق Domain و بخشهایی از Adaptation بدون نیاز به FastAPI یا Database تست میشوند.در Integration Test نیز یک SQLite موقت به همراه TestClient استفاده میشود تا ارتباط میان ماژولها بررسی شود.در زمان تهیه، مجموعهٔ تستها ۱۴۰ تست موفق داشته است. تستهای Integration مسائلی مانند RBAC، انتشار Eventها و فعال شدن Adaptation را از ابتدا تا انتهای مسیر بررسی میکنند.بنابراین Testability صرفاً یک نتیجهٔ جانبی نیست؛ یکی از دلایل اصلی جداسازی Domain، Application و Infrastructure است.تصمیمهای معماری در قالب ADRبرای اینکه تصمیمهای معماری فقط در ذهن توسعهدهنده نمانند، در قالب Architecture Decision Record مستند شده اند.مهمترین تصمیمها عبارتاند از:001 Modular Monolith به جای Microservices002 SQLite برای Prototype با آمادگی مهاجرت به MySQL003 Event Bus درونپردازشی به جای Message Broker004 JWT به جای Server-Side Session005 Rule-Based Adaptation به جای ML006 Layering درون هر Module به جای Shared Domain Layer007 Server-Rendered Jinja2 به جای SPA008 عدم استفاده از Docker/Kubernetes برای Prototype009 Ticket برای تغییر فیلدهای حساس هویتی010 اعمال Password Strength هنگام تغییر رمز به جای Registrationوجود این ADRها یک نکتهٔ مهم معماری را نشان میدهد:معماری فقط مجموعهای از فایلها نیست؛ مجموعهای از تصمیمها و دلایل پشت آن تصمیمهاست.چرا Kafka، RabbitMQ یا Event Broker واقعی نداریم؟ممکن است این سؤال مطرح شود که اگر سیستم Event-Driven است، چرا از Kafka یا RabbitMQ استفاده نشده است؟پاسخ از اولویتهای پروژه میآید:. Event Bus این پروژه یک کار مشخص دارد: کاهش Coupling بین ماژولها.. برای رسیدن به این هدف، یک Publish/Subscribe درونپردازشی کافی است.. استفاده از Broker واقعی، یک Process دیگر، Serialization، مدیریت Failureهای بیشتر، راهاندازی زیرساخت و هزینهٔ عملیاتی وارد پروژه میکرد.در نتیجه برای این Prototype، آن مزیتها ارزش هزینهٔ خود را نداشتند. این تصمیم به معنی بد بودن Kafka یا RabbitMQ نیست؛ بلکه به معنی نامتناسب بودن آنها با مسئلهٔ حاضر است.چرا Microservice نداریم؟همین منطق دربارهٔ Microservice نیز صدق میکند.اگر Appointment، Billing، Notification و Authentication هرکدام سرویس جداگانهای بودند، مسائل توزیعشدهٔ جدیدی ایجاد میشدند.اما در این پروژه، هدف اصلی مطالعهٔ:. Separation of Concerns. Modularity. Quality Attributes. Event-Driven Communication. Adaptation. Testabilityاست.بنابراین، انتخاب Modular Monolith امکان میدهد این مفاهیم با پیچیدگی عملیاتی بسیار کمتر بررسی شوند.چرا Docker و Kubernetes نداریم؟Docker و Kubernetes در این پروژه حذف شدهاند، نه به دلیل اینکه معماری مدرن نیستند، بلکه دقیقاً به دلیل توجه به Scope.سیستمی که قرار است بهصورت محلی و در یک Process اجرا شود، از Orchestration سود آموزشی کافی نمیبرد. اضافه کردن چنین زیرساختی بخش قابل توجهی از زمان را صرف Deployment و Operations میکند، در حالی که هدف پروژه بررسی تصمیمهای معماری نرمافزار است.چرا SQLite؟برای Prototype، SQLite انتخاب شده است؛ چون بدون Configuration پیچیده اجرا میشود و یک گزینهٔ مناسب برای تست و Demo محلی است.در عین حال، Repository Pattern باعث شده Persistence از Business Logic جدا بماند؛ بنابراین مهاجرت به MySQL در آینده نیازمند بازنویسی منطق Use Caseها نیست.این تصمیم نمونهٔ خوبی از یک Trade-off است:امروز سادگی اجرا مهمتر است، اما معماری نباید امکان رشد فردای سیستم را از بین ببرد.چرا Frontend ساده است؟Frontend پروژه با Server-Rendered HTML و Jinja2 ساخته شده و Framework سنگینی مانند React یا Angular در آن وجود ندارد.علت اصلی این تصمیم نیز کاهش پیچیدگی است:. Build Step وجود ندارد.. Bundler وجود ندارد.. Client-State پیچیده وجود ندارد.. برای یک Prototype آموزشی، نگهداری UI سادهتر است.در این پروژه قرار نبوده Frontend موضوع اصلی باشد؛ Frontend باید آنقدر خوب باشد که Architecture قابل نمایش و تست شود.یک نکتهٔ مهم دربارهٔ Clean Architectureیکی از درسهای مهم پروژه، این است که Clean Architecture نباید به معنای ایجاد تعداد زیادی Folder و Interface و Abstraction فهمیده شود.اصل مهم، Dependency Direction و جداسازی مسئولیتها است.در HISS:. UI نباید منطق کسبوکار را در خودش نگه دارد.. Application نباید به Template وابسته باشد.. Business Rule نباید به Database وابسته باشد.. Integration باید پشت مرز مشخص قرار گیرد.. تست Domain باید بدون UI و Database ممکن باشد.. اما در عین حال، هر انتزاعی فقط زمانی اضافه شده که ارزش معماری مشخصی ایجاد کند.این دقیقاً دلیل وجود Domain Layer where warranted در بعضی ماژولهاست؛ در appointments و billing منطق دامنهٔ واقعیتر و مستقلتری وجود دارد، اما در برخی ماژولهای دیگر، منطق آنقدر ساده است که قرار دادن آن در Service Layer منطقیتر بوده است.ارزیابی نهایی معماریبرای ارزیابی، سؤال اصلی این نیست که آیا سیستم چند قابلیت دارد؛ بلکه باید پرسید:آیا معماری واقعاً Quality Attributeهای هدف را پشتیبانی میکند؟Availabilityبا Graceful Degradation، Adapter Failure به Failure کل سیستم تبدیل نمیشود.Performanceبا تمرکز روی Hot Pathهای جستوجو و نوبتدهی، معیارهای زمانی مشخص شده و تستهای مربوط به آنها وجود دارند.SecurityAuthentication، Authorization، Object-Level Authorization، Audit و Login Lockout یک مرز امنیتی چندلایه ایجاد میکنند.IntegrabilityAdapter Boundary و Event Bus وابستگی مستقیم به سرویسهای بیرونی و Side Effectها را کاهش میدهند.Self-AdaptationMAPE-K اجازه میدهد سیستم در زمان اجرا نسبت به Load، Failure و Abuse واکنش نشان دهد.Testabilityمنطق مرکزی بدون UI و Database قابل آزمون است.ModifiabilityModule Boundary، Adapter Boundary و Event Boundary باعث میشوند بعضی قابلیتهای آینده بدون بازنویسی گستردهٔ Core اضافه شوند.یک نقص واقعی که در فرآیند ارزیابی پیدا شدیکی از نکات ارزشمند این پروژه این است که نتیجهٔ ارزیابی فقط شامل نقاط قوت نیست.یک مشکل واقعی در Admin Monitor پیدا شد: جدول وضعیت Mock Adapterها در یک Database تازه میتوانست خالی باشد.دلیل آن این بود که API مربوط به Adapterها در صورت نبودن Rowها آنها را Lazy-Creation میکرد، اما مسیر UI مستقیماً Rowهای موجود را میخواند و خودش آنها را ایجاد نمیکرد. در نتیجه روی یک سیستم تازه، ممکن بود مدیر داشبوردی بدون Adapter قابل مشاهده ببیند.این مشکل عمداً اینجا پنهان نشده است و بهعنوان یک Gap واقعی معماری و پیادهسازی ثبت شده و راهحل پیشنهادی آن نیز مشخص شد: Seed کردن Rowهای اولیه یا استفاده از همان منطق getor_create() در مسیر UI.بنابراین معماری خوب فقط به معنای داشتن Diagram زیبا نیست؛ معماری باید با رفتار واقعی سیستم هم تطبیق داده شود.CIA, mapped to actual code — and a real bug this project shipped and fixedbefore and after of app/templates/invoice_view.htmlچه چیزهایی میتوانند در آینده اضافه شوند؟ساختار پروژه عمداً طوری طراحی شده که چند قابلیت بتوانند بدون بازنویسی گسترده به آن اضافه شوند.اتصال واقعی به بیمه، داروخانه و آزمایشگاهبا جایگزین کردن Adapterهای Mock با Adapterهای واقعی.Telemedicineمیتواند بهصورت یک ماژول جدید وارد همین معماری شود.EMR/EHR بهترمدل فعلی عمداً فقط خلاصهٔ پرونده را نگه میدارد و میتوان آن را گسترش داد.Role جدید برای Technical Staffمدل Authorization بهگونهای طراحی شده که اضافه کردن Role جدید نیازمند بازنویسی ساختار اصلی نیست.MySQLRepository Boundary برای مهاجرت Persistence طراحی شده است.جمعبندیHISS در ظاهر یک سامانهٔ کوچک بیمارستانی است، اما مسئلهٔ اصلی پروژه، تعداد قابلیتها نیست. موضوع اصلی، معماری بهعنوان مجموعهای از تصمیمهای آگاهانه برای رسیدن به کیفیتهای مورد نظر است.در این پروژه تلاش شد نشان داده شود که میتوان بدون رفتن به سمت زیرساختهای سنگین، همچنان مفاهیم مهم معماری را در یک نمونهٔ عملی پیاده کرد:. یک Modular Monolith بهجای Microservices. Layering درون هر Module. Event-Driven Communication برای کاهش Coupling. Adapter برای Integrability. Graceful Degradation برای Availability. RBAC و Object-Level Authorization برای Security. MAPE-K برای Self-Adaptation. Unit و Integration Test برای Testability. ADR برای ثبت تصمیمها و Trade-offهاشاید مهمترین نتیجهٔ این پروژه همین باشد که معماری نرمافزار مجموعهای از تکنولوژیهای پرزرقوبرق نیست. گاهی انتخاب Kafka یا Kubernetes معماری نیست؛ انتخاب نکردن آنها و داشتن یک دلیل روشن برای انتخاب نکردنشان، خود یک تصمیم معماری است.گاهی Self-Adaptive بودن به معنی استفاده از Machine Learning نیست؛ چند Rule شفاف که دقیقاً مشخص کنند سیستم در یک وضعیت غیرعادی چگونه رفتار خود را تغییر میدهد، میتواند برای مسئلهٔ مورد نظر کافی و حتی مناسبتر باشد.و در نهایت، یک معماری زمانی ارزشمند است که بتوان برای تصمیمهای آن پاسخ &#34;چرا&#34; داشت.HISS تلاشی است برای ساختن چنین سیستمی؛ سیستمی کوچک از نظر زیرساخت، اما جدی از نظر استدلال معماری.منابع۱. Bass, L., Clements, P., Kazman, R. — Software Architecture in Practice.۲. Martin, R. C. — Clean Architecture: A Craftsman&#39;s Guide to Software Structure and Design.۳. مستندات توضیحات پروژهٔ HISS.به دلیل وجود مشکل در پلتفرم ویرگول و عدم امکان بارگذاری گزارش پروژه، ویدیوی منتشر شده از گزارش پروژه در آپارات مشاهده شود:https://www.aparat.com/v/zdi0190اين مطلب، بخشی از تمرين ها و پروژه درس معماری نرمافزار دانشگاه شهيد بهشتی است.این پست تبلیغاتی نیست.</description><category>Maedeh Zarei</category><author>Maedeh Zarei</author><pubDate>Wed, 12 Aug 2026 16:43:24 +0330</pubDate></item><item><title>پروژه درس معماری نرم‌افزار، سامانهٔ اطلاعات و خدمات بیمارستانی HISS</title><link>https://virgool.ir/@MaedehZarei/معماری-نرم-افزار-b4a9lw20kja6</link><description>وقتی صحبت از یک سامانهٔ بیمارستانی می‌شود، اولین تصویری که معمولاً به ذهن می‌رسد مجموعه‌ای از قابلیت‌های مختلف مانند ثبت بیمار، جست‌وجوی پزشک، نوبت‌دهی، پروندهٔ پزشکی و صدور صورتحساب است. اما در یک پروژهٔ معماری نرم‌افزار، پرسش اصلی فقط این نیست که سیستم چه کارهایی انجام می‌دهد؛ پرسش مهم‌تر این است که این سیستم چرا باید به این شکل طراحی شود و این طراحی چگونه کیفیت‌های مورد انتظار را در شرایط واقعی تضمین می‌کند؟پروژهٔ HISS یا Hospital Information and Service System با همین نگاه طراحی شده است؛ یک نمونهٔ کوچک اما معماری‌محور از سامانهٔ اطلاعات و خدمات بیمارستانی که هدف آن، بیش از آن که شبیه‌سازی کامل یک بیمارستان واقعی باشد، نمایش تصمیم‌های معماری، trade-offها، سناریوهای کیفیتی، جداسازی مسئولیت‌ها، ارتباط رویدادمحور و یک حلقهٔ خودسازگار سبک است.در این پروژه تلاش شده است میان سادگی لازم برای یک نمونهٔ دانشجویی و بررسی متعادل معماری برقرار شود. بنابراین سیستم عمداً به یک زیرساخت توزیع‌شدهٔ سنگین تبدیل نشده و در عوض، معماری آن بر پایهٔ یک Modular Monolith، لایه‌بندی داخلی هر ماژول، ارتباط Event-Driven درون‌برنامه‌ای، الگوی Adapter برای یکپارچه‌سازی و یک حلقهٔ MAPE-K مبتنی بر Rule بنا شده است.HISS — Hospital Information &amp; Service Systemمسئله و زمینهٔ کسب و کارHISS تصویری ساده‌شده از گردش کار روزمرهٔ یک بیمارستان ارائه می‌دهد. در این محیط، بیمار ثبت می‌شود، پزشک جست‌وجو می‌شود، برای بیمار نوبت ثبت می‌شود، اطلاعات پایهٔ پزشکی در دسترس قرار می‌گیرد، صورتحساب ساخته می‌شود و در صورت نیاز، سیستم با سرویس‌هایی مانند بیمه، داروخانه یا آزمایشگاه تعامل می‌کند.چهار نقش اصلی در سیستم وجود دارند:. بیمار. پزشک. پذیرش. مدیر سیستمبیمار می‌تواند پزشک را جست‌وجو کند، نوبت بگیرد و اطلاعات مجاز مربوط به خود را مشاهده یا ویرایش کند. پذیرش علاوه بر ثبت بیمار، در فرآیندهای نوبت‌دهی و صورتحساب نقش دارد. پزشک برنامهٔ کاری و بیماران مرتبط با خود را مشاهده می‌کند و مدیر، بیشتر با جنبه‌های عملیاتی، پایش وضعیت سیستم، رخدادهای سازگاری و درخواست‌های مدیریتی سر و کار دارد.از طرف دیگر، سه سیستم بیرونی که در یک بیمارستان واقعی میتوانند وجود داشته باشند، در این پروژه به صورت Mock Adapter مدل شدهاند:. سامانهٔ بیمه. سامانهٔ داروخانه. سامانهٔ آزمایشگاهنکتهٔ معماری اینجا مهم است. هدف پروژه شبیه‌سازی شبکه و API واقعی این سرویس‌ها نیست؛ هدف این است که مرز یکپارچه‌سازی به‌شکل واقعی طراحی شود تا در آینده بتوان پیاده‌سازی Mock را با یک سرویس واقعی جایگزین کرد.Fig. 2 — c4 model,context diagram. Three &#34;external&#34; systems exist only as mock adapters — the boundary is drawn honestly rather than implying a real integration.محدودهٔ سیستمقابلیت‌های اصلی HISS شامل این موارد است:. احراز هویت و مدیریت کاربران. مدیریت اطلاعات بیمار. نمایش خلاصهٔ پروندهٔ پزشکی. جست‌وجوی پزشک. مشاهدهٔ زمان‌های قابل رزرو. ثبت، لغو و تغییر نوبت. مدیریت اولویت نوبت‌های اضطراری. ایجاد فاکتور. محاسبهٔ هزینه و وضعیت بیمه. اعلان‌های سیستم. اتصال Mock به بیمه، داروخانه و آزمایشگاه. داشبورد مدیریتی و پایش وضعیت سیستم. ثبت رخدادهای عملیاتی و امنیتی. مدیریت درخواست‌های تغییر برخی اطلاعات حساس پروفایلدر مقابل، پروژه عمداً وارد حوزه‌هایی مانند Telemedicine کامل، پیچیدگی کامل EMR/EHR، پرداخت واقعی، انبار دارو، LIS واقعی، PACS، فرآیند کامل اورژانس و زیرسیستم‌های اداری بیمارستان نمی‌شود. این محدودسازی بخشی از تصمیم معماری پروژه است و نه یک کمبود تصادفی. هدف آن است که ظرفیت پروژه صرف نمایش استدلال معماری شود، نه پیاده‌سازی زیرساختی که از مسئلهٔ اصلی دور شود.از Functionality تا Quality Attributeیکی از مهم‌ترین تفاوت‌های دیدگاه معماری نرم‌افزار با توسعهٔ صرفاً قابلیت‌محور، توجه به Quality Attributeها است.در این پروژه، کیفیت‌ها به‌صورت صفت‌های مبهم مانند &#34;سیستم سریع باشد&#34; یا &#34;سیستم امن باشد&#34; در نظر گرفته نشده‌اند.برای هر کیفیت، باید بتوان مشخص کرد:. چه چیزی را اندازه می‌گیریم؟. در چه شرایطی؟. با چه هدفی؟. اگر سیستم با یک محرک خاص مواجه شد، چه واکنشی باید نشان دهد؟این نگاه با الگوی سناریوهای Quality Attribute که در درس معماری نرم‌افزار مطرح می‌شود هم‌راستا است. در پروژه، سناریوها به اجزایی مانند منبع محرک، خود محرک، محیط، Artifact، پاسخ و معیار پاسخ شکسته شده‌اند.Quality Attribute Scenarios Includes: Stimulus source, Stimulus, Environment, Artifact, Response, Response measureاولویت Quality Attributeهااز همان ابتدا برای کیفیت‌های سیستم یک ترتیب اولویت مشخص در نظر گرفته شد:1. Availability2. Performance3. Security4. Integrability5. Modern Architectural Topics6. Testability7. Maintainability / Modifiabilityاین ترتیب صرفاً یک فهرست نیست. مهم‌ترین کاربرد آن زمانی مشخص می‌شود که دو کیفیت با یکدیگر تعارض دارند.برای مثال، استفاده از bcrypt هزینهٔ محاسباتی بیشتری نسبت به روش‌های ساده‌تر دارد، اما به دلیل اهمیت Security قابل توجیه است. از طرف دیگر، در مسیرهای پرتکرار مانند جست‌وجو و نوبت‌دهی، Performance اهمیت بیشتری پیدا می‌کند. به بیان دیگر، Quality Attributeها رایگان نیستند و هر تصمیم معماری روی چند کیفیت اثر می‌گذارد. بنابراین معماری به یک اولویت صریح نیاز دارد تا هنگام تعارض بتواند تصمیم بگیرد کدام کیفیت در آن پروژه مهم‌تر است.معماری انتخاب شدهمعماری HISS از ترکیب چند ایده شکل گرفته است:Modular Monolith + Layered Architecture + Event-Driven Communication + Rule-Based Self-Adaptationدر نگاه اول ممکن است این ترکیب متناقض به نظر برسد؛ چون Event-Driven و MAPE-K گاهی با سیستم‌های توزیع‌شده، Microserviceها و زیرساخت‌های پیچیده تداعی می‌شوند. اما در این پروژه این مفاهیم در اندازهٔ یک برنامهٔ تک‌فرآیندی پیاده‌سازی شده‌اند.چرا Modular Monolith؟HISS یک برنامهٔ قابل استقرار دارد، اما داخل آن به چندین ماژول مستقل تقسیم شده است.ماژول‌های اصلی شامل این بخش‌ها هستند:. Authentication. Patients. Doctors. Appointments. Billing. Notifications. Integrations. Profile. Tickets. Events. Adaptation. Auditاین ساختار اجازه می‌دهد سیستم از نظر فیزیکی ساده باقی بماند، اما از نظر منطقی مانند مجموعه‌ای از زیرسیستم‌های مستقل سازمان‌دهی شود. در ارائهٔ پروژه، این ساختار در قالب دوازده ماژول و یک پردازش اصلی FastAPI مستند شده است.در نتیجه، یک ماژول جدید لزوماً نباید به فایل‌ها و پوشه‌های مشترک همهٔ ماژول‌های دیگر دست بزند.این انتخاب آگاهانه در مقابل Microservices قرار گرفته است. تبدیل دوازده ماژول داخلی به سرویس‌های شبکه‌ای، مسئله‌های دیگری مانند Service Discovery، Serialization، Failureهای شبکه، Partial Failure و مدیریت چند Process را وارد پروژه می‌کرد؛ مسائلی که برای این نمونهٔ دانشگاهی نه‌ تنها ضروری نبودند، بلکه تمرکز را از بحث معماری مورد نظر دور می‌کردند.Fig. 3 — c4 model,container diagram. &#34;Container&#34; is the C4 sense (an independently runnable unit) — not Docker. There is deliberately exactly one running process (ADR 008).Fig. 4 — c4 model, component diagram (relationship list trimmed for legibility — the file on disk lists every module&#39;s core dependency too). No Code-level (4th) C4 diagram is maintained by hand, per the course&#39;s own guidance.چهار لایه، اما درون هر ماژولیکی از تصمیم‌های مهم HISS این است که لایه‌بندی به‌شکل یک ساختار سراسری مانند api/, service/, domain/ و repository/ در نظر گرفته نشده است.در عوض، هر ماژول تا حد امکان ساختار لایه‌ای خودش را دارد:app/appointments/api.pyservice.pydomain.pyrepository.pymodels.pyدر نتیجه، چهار لایهٔ مفهومی عبارت‌اند از:Presentationمسئول Routeها، شکل ورودی و خروجی درخواست‌ها و تعامل با UI است.Applicationمنطق Use Case، orchestration، تراکنش‌ها و کنترل دسترسی در این لایه قرار دارد.Domainقوانین کسب‌وکار خالص، بدون دسترسی مستقیم به I/O، در این بخش قرار می‌گیرند؛ البته فقط در ماژول‌هایی که واقعاً به منطق دامنهٔ غنی نیاز دارند.Infrastructureمسئول Persistence و تعامل با SQLAlchemy و سایر جزئیات فنی است.این موضوع با ایدهٔ Clean Architecture در جداسازی وابستگی‌ها و حفاظت از منطق کسب‌وکار هم‌جهت است، اما پروژه یک پیاده‌سازی کاملاً کلاسیک و یکسان از آن ارائه نمی‌دهد. تصمیم عملی پروژه این بوده که لایه‌ها درون Feature Moduleها قرار بگیرند.Fig. 5 — the stack repeated identically in auth/, patients/, appointments/, ... Only appointments and billing have a real domain.py — other modules&#39; logic is thin enough to live directly in service.py, which is itself a documented, deliberate choice, not an inconsistency.patient dashboarddoctor dashboardreceptionist dashboardadmin dashboardبه دلیل وجود مشکل در پلتفرم ویرگول و عدم امکان بارگذاری گزارش پروژه، ویدیوی منتشر شده در آپارات مشاهده شود:https://www.aparat.com/v/zdi0190همچنین از طریق لینک پیشنویس زیر، می­توانید گزارش کامل پروژه را مشاهده نمایید:https://virgool.io/@MaedehZarei/d/upkxhl4nerivپست شرح کامل پروژه نیز در ویرگول منتشر شد:https://vrgl.ir/dWWQLاين مطلب، بخشی از تمرين ها و پروژه درس معماری نرم افزار دانشگاه شهيد بهشتی است.</description><category>Maedeh Zarei</category><author>Maedeh Zarei</author><pubDate>Wed, 12 Aug 2026 16:02:52 +0330</pubDate></item><item><title>معماری نرم‌افزار، از ساختار تیم‌ها تا جریان ارزش؛ مروری بر کتاب Team Topologies</title><link>https://virgool.ir/@MaedehZarei/معماری-نرم-افزار-از-ساختار-تیم-ها-تا-جریان-ارزش-مروری-بر-کتاب-team-topologies-rvnjwiioinvm</link><description>وقتی درباره‌ معماری نرم افزار صحبت می‌کنیم، معمولا ذهنمان به سمت Componentها، Moduleها، Serviceها، Interfaceها، Databaseها و نحوه‌ ارتباط آن‌ها می‌رود. با این حال، یک سؤال مهم معمولاً کمتر دیده می‌شود: چه کسانی قرار است این معماری را بسازند، تغییر دهند و در طول زمان از آن مراقبت کنند؟کتاب Team Topologies: Organizing Business and Technology for Fast Flow of Value نوشته‌Matthew Skelton و Manuel Pais دقیقاً از همین منظر معماری را بررسی می کند. انتشار اولیه این کتاب در سال ۲۰۱۹ و بازنگری آن در سال ۲۰۲۵ با عنوان Second Edition صورت گرفت. نسخه‌ دوم کتاب، دارای ساختار سه بخشی به شرح زیر است:Teams as the Means of Delivery, Team Topologies That Work for Flow &amp; Evolving Team Interactions for Innovation and Rapid Delivery. [1]ایده‌ مطرح شده در کتاب به این می پردازد که توسعه و بهره‌برداری از نرم‌افزار را نمی‌توان صرفاً یک مسئله‌ فنی دانست. Software Delivery یک Sociotechnical System است؛ یعنی نتیجه‌ تعامل میان انسان‌ها، تیم‌ها، ساختار سازمانی، فناوری و معماری نرم‌افزار است. بنابراین اگر تیم‌ها و روابط میان آن‌ها به درستی طراحی نشده باشند، حتی یک معماری فنی خوب نیز ممکن است در عمل نتواند جریان مناسبی از تغییرات را ایجاد کند.هدف نهایی Team Topologies، چیزی است که نویسندگان آن را Fast Flow of Value می‌نامند؛ یعنی حرکت سریع و ایمن تغییرات و ارزش کسب‌ و کاری از ایده تا رسیدن به کاربر با کاهش انتظار، وابستگی، تحویل‌های بین‌ تیمی و سربار هماهنگی. کتاب تأکید می‌کند که برای رسیدن به این هدف، باید هم ساختار تیم‌ها و هم نحوه‌ تعامل آن‌ها را آگاهانه طراحی کرد. [1]از این منظر، Team Topologies را نمی‌توان صرفاً درباره‌ی مدیریت تیم‌ها دانست. بخش مهمی از استدلال کتاب به این موضوع مربوط است که ساختار تیم‌ها چگونه روی ساختار Software Architecture اثر می‌گذارد و چگونه می‌توان از آن آگاهانه بهره برد.Team Topologies: Organizing Business and Technology for Fast Flow of Value by Matthew Skelton &amp; Manuel PaisPart I — Teams as the Means of Deliveryبخش اول کتاب با عنوان Teams as the Means of Delivery، پایه‌های فکری Team Topologies را می‌سازد:اگر Team واحد اصلی تحویل نرم‌افزار است، این تیم‌ها را چگونه باید شکل داد و چه رابطه‌ای باید بین آن‌ها وجود داشته باشد؟فصل اول نشان می‌دهد که ساختار رسمی سازمان با نحوه‌ واقعی انجام کار یکسان نیست. فصل دوم توضیح می‌دهد که ساختار ارتباطی تیم‌ها می‌تواند معماری نرم‌افزار را شکل دهد. فصل سوم نیز این بحث را به خود تیم می‌رساند و می‌پرسد یک تیم مؤثر چه اندازه‌ای دارد، چه چیزی را باید مالک شود و چگونه باید Cognitive Load آن را کنترل کرد.Chapter 1 — The Problem with Org Chartsچرا Org Chart برای طراحی Software Delivery کافی نیست؟Org Chart یا نمودار سازمانی، ساختار رسمی است که سازمان را نمایش می‌دهد؛ یعنی واحدها، تیم‌ها و روابط گزارش‌دهی میان آن‌ها. این نمودار برای موضوعاتی مانند مدیریت، مسئولیت رسمی و الزامات قانونی مفید است، اما Team Topologies استدلال می‌کند که برای توضیح نحوه‌ واقعی انجام کار در محیط‌های پیچیده‌ی نرم‌افزاری کافی نیست. [1]مشکل اصلی زمانی ایجاد می‌شود که تصور کنیم خطوط موجود در Org Chart همان مسیرهای واقعی ارتباط هستند.در یک سازمان نرم‌افزاری، یک برنامه‌نویس ممکن است از نظر رسمی عضو یک تیم باشد، اما برای حل یک مسئله‌ دائماً با توسعه‌دهندگان تیم دیگر، متخصص زیرساخت، مسئول امنیتی یا شخصی از تیم عملیات در ارتباط باشد. بنابراین مسیر واقعی ارتباطات اغلب افقی یا Lateral است، نه صرفاً عمودی و سلسله‌مراتبی.کتاب در توضیح این وضعیت تأکید می‌کند که افراد در عمل با کسانی ارتباط برقرار می‌کنند که برای انجام کار به آن‌ها نیاز دارند، حتی اگر این ارتباط در Org Chart دیده نشود. [1]یک مثال سادهفرض کنیم در ساختار رسمی سازمان چنین چیزی داریم: مدیریت، Team B، Team A و Team Cدر واقعیت، برای تحویل یک Feature، تیم A باید دائماً منتظر تیم B باشد و تیم B نیز برای تغییر Database به یک متخصص مرکزی مراجعه کند. در این حالت، اگر فقط Org Chart را ببینیم، ممکن است تصور کنیم سه تیم نسبتاً مستقل داریم. اما در عمل، یک شبکه‌ پیچیده از Dependencyها وجود دارد که مسیر واقعی تحویل را تعیین می‌کند.بنابراین مسئله‌ی اصلی این است که Org Chart، ساختار رسمی را نشان می‌دهد، اما Software Delivery به ساختار واقعی ارتباط و جریان کار وابسته است.سه ساختار متفاوت در سازمانکتاب در این بحث از دیدگاه Niels Pflaeging استفاده می‌کند که در هر سازمان، سه نوع ساختار را باید از هم تفکیک کرد: Formal Structure (ساختار رسمی که همان Org Chart است و روابط رسمی سازمان را نشان می‌دهد)، Informal Structure (شبکه‌ و روابط غیررسمی میان افراد و تیم‌ها؛ برای مثال اینکه در عمل چه کسی مرجع تصمیم‌گیری یا حل مسئله محسوب می‌شود) و Value Creation Structure (نحوه‌ واقعی انجام کار؛ یعنی اینکه افراد و تیم‌ها در عمل چگونه با یکدیگر تعامل می‌کنند تا ارزش تولید شود). [1]برای محیط‌های دانش‌محور مانند Software Engineering، دو ساختار آخر از اهمیت ویژه‌ای برخوردارند، چرا که ارزش واقعی از طریق تعاملات میان افراد و تیم‌ها ایجاد می‌شود.Local Optimization در برابر Fast Flowیکی از نکات مهم این فصل، تفاوت میان Local Optimization و بهینه‌سازی جریان کل سیستم است.فرض کنیم یک تیم موفق شده زمان انجام کار خودش را نصف کند. اگر تیم بعدی همچنان گلوگاه باشد، این بهبود الزاماً باعث سریع‌تر شدن تحویل نهایی نمی‌شود. به همین دلیل Team Topologies نگاه Systems Thinking را مطرح می‌کند: باید به کل جریان نگاه کرد و مهم‌ترین Bottleneck را پیدا و برطرف کرد، نه اینکه صرفاً یک بخش کوچک را بهینه کنیم. [1] هدف این دیدگاه، Fast Flow of Value است.Fast Flow به معنی کدنویسی سریع‌تر نیست؛ موضوع این است که یک تغییر بتواند از مرحله‌ ایده تا استفاده‌ واقعی، با کمترین انتظار، Dependency و Handoff حرکت کند. بنابراین اگر یک تیم فوق‌العاده سریع باشد، اما برای هر Release مجبور باشد چند روز منتظر تیم دیگری بماند، سرعت آن تیم به‌ تنهایی جریان کار کل سیستم را افزایش نمی‌دهد.این نگاه به‌وضوح ریشه‌ یکی از ایده‌های اصلی Team Topologies را نشان می‌دهد:«به‌جای بهینه‌سازی افراد یا تیم‌های منفرد، باید جریان ارزش در کل سیستم را بهینه کرد.»چرا سازمان‌های ایستا مشکل‌ساز می‌شوند؟در مهندسی نرم افزار، فناوری، بازار، نیازهای مشتری و حتی خود محصول دائماً تغییر می‌کنند. بنابراین ساختاری که امروز منطقی است، ممکن است چند ماه بعد به یک Bottleneck تبدیل شود. مدل‌های سازمانی سنتی مانند ساختارهای صرفاً Functional یا حتی Matrix Management این جهت مورد انتقاد هستند که اغلب تصویری Static از سازمان ارائه می‌کنند. بنابراین، کتاب وجود یک مدل Adaptive را مطرح می‌کند؛ مدلی که بتواند با تغییر شرایط، ساختار تیم‌ها و نحوه‌ تعامل آن‌ها را نیز تغییر دهد. [1]این ایده در بخش‌های بعدی کتاب به Organizational Sensing و تکامل مداوم Team Topologies منجر می‌شود، اما ریشه‌ی آن در همین فصل اول قرار دارد.به طور خلاصه، Chapter 1 می‌گوید:برای درک نحوه‌ی واقعی تحویل نرم‌افزار، نباید فقط Org Chart را ببینیم؛ باید Communication Structure و نحوه‌ی واقعی خلق ارزش را نیز در نظر بگیریم.Chapter 2 — Conway’s Law and Why It MattersConway’s Law چیست؟Mel Conway در سال ۱۹۶۸ رابطه‌ای میان ساختار سازمانی و ساختار سیستم‌هایی که سازمان تولید می‌کند مطرح کرد که در کتاب، تعریف آن به این شکل نقل شده است:&#34;Organizations which design systems...are constrained to produce designs which are copies of the communication structures of these organizations.&#34; [1]سازمانی که یک سیستم را طراحی می‌کند، تحت تأثیر ساختار ارتباطی خودش قرار دارد و معماری‌ای که ایجاد می‌کند تمایل دارد همان الگوی ارتباطی را منعکس کند.[1] Skelton, M., &amp; Pais, M. Team Topologies, 2nd ed., Chapter 2.کتاب برای توضیح این ارتباط از مفهوم Homomorphic Force نیز استفاده می‌کند. منظور از آن، نیرویی است که باعث می‌شود Software Architecture و Team Structure به سمت یک شکل مشابه حرکت کنند. بنابراین برای فهم اینکه چه معماری‌ای در یک سازمان واقعاً قابل دستیابی است، باید نحوه‌ ارتباط تیم‌ها را بشناسیم. [1]مثال چهار تیم و یک DBAکتاب برای توضیح این موضوع یک مثال بسیار روشن ارائه می‌کند.فرض کنید چهار تیم روی چهار بخش مختلف یک سیستم کار می‌کنند. هر تیم، توسعه‌دهنده‌ Front-end و Back-end دارد، اما برای تغییرات Database مجبور است به یک DBA مرکزی مراجعه کند.در نتیجه ساختار ارتباطی تقریباً چنین است:Figure 2.1: Four Teams Working on a Software SystemConway’s Law پیش‌بینی می‌کند معماری‌ای که طبیعی‌تر است به سمت چنین ساختاری حرکت کند:Figure 2.2: Software Architecture from Four-Team Organizationاین دقیقاً همان ارتباطی است که کتاب در Figures 2.1 و 2.2 توضیح می‌دهد: تیم‌های جداگانه به یک DBA مرکزی وابسته‌اند و همین ساختار ارتباطی، احتمال شکل‌گیری یک Shared Database را افزایش می‌دهد. [1]اگر هدف معماری ما همین باشد، مشکلی وجود ندارد، اما فرض کنیم می‌خواهیم Microservices مستقل داشته باشیم که هرکدام Data Store خود را نیز داشته باشند. در این صورت ساختار تیمی قبلی با Architecture مطلوب سازگار نیست.Reverse Conway Maneuverدر Reverse Conway Maneuver، به‌ جای اینکه فقط معماری را طراحی کنیم و امیدوار باشیم ساختار تیم‌ها در نهایت با آن هماهنگ شود، تیم‌ها را از ابتدا طوری طراحی می‌کنیم که Communication Structure مورد نیاز Architecture مطلوب را ایجاد کنند.در مثال بالا، اگر هدف ما داشتن چهار Service مستقل باشد، به‌جای یک DBA مرکزی، قابلیت Database را در خود تیم مربوط به هر Service قرار می‌دهیم.به این ترتیب:Figure 2.4: Team Design for Microservices Architecture with Independent Services and Data Storesساختار تیمی اکنون با Architecture مورد نظر هم‌راستا شده است.این رویکرد به‌ ویژه زمانی مهم است که بخواهیم بخش‌های مختلف یک سیستم را مستقل و با حداقل Dependency میان تیم‌ها توسعه دهیم. [1]Architecture باید Team-Scoped Flow را پشتیبانی کند.در ادامه‌ی فصل دوم، بحث مهم دیگری مطرح می‌شود: Team-Scoped Flow، یعنی جریان تغییرات تا حد امکان باید در محدوده‌ یک تیم باقی بماند. اگر برای هر تغییر کوچک مجبور باشیم چند تیم را هماهنگ کنیم، جریان تحویل به انتظار و هماهنگی وابسته می‌شود.کتاب برای رسیدن به این وضعیت، چند اصل شناخته‌شده‌ معماری را مطرح می‌کند:- Loose Coupling؛ وابستگی شدید میان اجزای سیستم کاهش یابد.- High Cohesion؛ مسئولیت‌های یک Component تا حد امکان مشخص و مرتبط باشند.- Clear Version Compatibility؛ سازگاری میان بخش‌های مختلف روشن باشد.- Clear Cross-Team Testing؛ تست هایی که از مرز تیم‌ها عبور می‌کنند، آگاهانه مدیریت شوند. [1]در نتیجه معماری از نگاه Team Topologies باید بتواند نحوه‌ واقعی کار کردن تیم‌ها را نیز تسهیل کند.در نهایت، اگر تعیین کنیم چه تیمی مسئول چه Software Subsystemی باشد، عملاً بخشی از Architecture را نیز تعیین کرده‌ایم. به همین دلیل طراحی سازمان و طراحی نرم‌افزار کاملاً مستقل از یکدیگر نیستند. کتاب حتی تأکید می‌کند تصمیم‌های مربوط به شکل، مسئولیت و مرزهای تیم‌های فنی باید با درک کافی از Architecture گرفته شوند. [1]Chapter 3 — Team-First Thinking«تیم، واحد بنیادین تحویل نرم‌افزار است.»در نگاه Team Topologies، تیم صرفاً مجموعه‌ای از افراد با یک مدیر مشترک نیست. یک تیم واقعی باید ماموریت، هدف، یادگیری و سطح مناسبی از هماهنگی را داشته باشد و بتوانند با هم کار کنند و با هم یاد بگیرند. [1]Small, Long-Lived Teamsکتاب اندازه‌ی مؤثر معمولی یک تیم را حدود ۷ تا ۹ نفر در نظر می‌گیرد و این موضوع را با محدودیت‌های ارتباط انسانی و مفهوم Dunbar’s Number مرتبط می‌کند. [1]Dunbar’s Number چیست؟Dunbar’s Number به محدودیت تقریبی انسان در نگهداری روابط اجتماعی پایدار اشاره دارد. Team Topologies از این ایده برای توضیح این موضوع استفاده می‌کند که تیم نیز ظرفیت محدودی برای ارتباط و هماهنگی دارد.در همین زمینه کتاب به ایده‌ Amazon’s Two-Pizza Teams نیز اشاره می‌کند؛ یعنی تیم‌ها باید آن‌قدر کوچک باشند که ارتباط و انسجام میان اعضای آن‌ها همچنان قابل مدیریت باشد. [1]هرچه Team بزرگ‌تر و روابط درون آن پیچیده‌تر شود، حفظ هماهنگی، اعتماد و درک مشترک دشوارتر می‌شود.چرا تیم‌ها باید Long-Lived باشند؟تیم‌ها برای تبدیل شدن به یک واحد واقعاً مؤثر، به زمان نیاز دارند. اعضا باید یکدیگر را بشناسند، روش کار مشترک ایجاد کنند، دامنه را بفهمند، اعتماد ایجاد کنند، و الگوهای حل مسئله‌ مشترک بسازند. به همین دلیل کتاب توصیه می‌کند تیم‌ها نسبتاً پایدار باشند و کار را به تیم بدهیم، نه اینکه دائماً افراد را بین پروژه‌ها جابه‌جا کنیم.این ایده با Brooks’s Law نیز مرتبط می‌شود: اضافه کردن افراد جدید به یک تیم الزاماً ظرفیت آن را فوراً افزایش نمی‌دهد، زیرا هماهنگی و Ramp-up نیز خود هزینه ایجاد می‌کنند. [1]بنابراین:«Stable does not mean Static.»تیم باید پایدار باشد، اما در صورت نیاز و با منطق مشخص تکامل پیدا کند.The Team Owns the Softwareمنظور از Ownership صرفاً داشتن دسترسی یا مسئولیت قراردادی نیست. هدف ایجاد چیزی است که کتاب آن را Continuity of Care می‌نامد. یعنی تیم فقط نرم افزار را نمی‌سازد، بلکه در طول عمر آن نیز درک و مسئولیت خود را حفظ می‌کند. این موضوع به Operability و توانایی تکامل تدریجی سیستم کمک می‌کند. [1]این دیدگاه بعدها در کتاب با رابطه‌ نزدیک‌تر میان Development و Operations نیز ادامه پیدا می‌کند.Cognitive LoadCognitive Load مقدار بار ذهنی مورد نیاز برای پردازش و انجام یک کار است. کتاب این مفهوم را بر اساس کار John Sweller در Cognitive Load Theory توضیح می‌دهد. [1]نویسندگان استدلال می‌کنند که همان‌طور که یک فرد ظرفیت محدودی برای پردازش اطلاعات دارد، یک تیم نیز ظرفیت محدودی برای درک و مدیریت پیچیدگی دارد؛ در نتیجه نمی‌توان به یک تیم تعداد نامحدودی Software Subsystem، Domain، Technology و Responsibility داد و انتظار داشت همچنان منسجم و مؤثر باقی بماند.سه نوع Cognitive Load داریم: Intrinsic Cognitive Load (پیچیدگی ذاتی خود مسئله)، Extraneous Cognitive Load (پیچیدگی‌ای که ناشی از خود مسئله نیست و از محیط انجام کار ایجاد می‌شود) و Germane Cognitive Load (بار ذهنی‌ای که مستقیماً برای یادگیری، درک عمیق مسئله و عملکرد بهتر صرف می‌شود؛ برای مثال فهم رابطه‌ درست میان دو Service). [1]هدف این است: کاهش Intrinsic Cognitive Load تا حد امکان، حذف Extraneous Cognitive Load و آزاد کردن ظرفیت ذهنی برای Germane Cognitive Load.کتاب برای کاهش این بار به راهکارهایی مانند آموزش، انتخاب مناسب فناوری، Pair Programming و به‌ ویژه Automation اشاره می‌کند. [1]اگر یک Software Subsystem آن‌قدر بزرگ و پیچیده شود که یک تیم دیگر نتواند تصویر کاملی از آن داشته باشد، تیم عملاً نمی‌تواند نرم افزار را به‌صورت مؤثر مالکیت بخشیده و توسعه دهد. بنابراین کتاب پیشنهاد می‌کند:&#34;اندازه‌ Software Subsystem نباید از Cognitive Capacity تیم مسئول آن فراتر برود.&#34; [1]Team-Sized Architectureدر Team-Sized Architecture مرزهای نرم افزار بر اساس محدودیت‌های انسانی و Cognitive Capacity تیم‌ها نیز در نظر گرفته می‌شوند. پس سؤال فقط این نیست که Monolith بهتر است یا Microservices، بلکه آیا این Software Boundary با ظرفیت شناختی تیمی که مسئول آن است سازگار است؟ به همین دلیل کتاب Team-Sized Architecture را یک رویکرد People-First می‌داند؛ رویکردی که الزاماً به Microservices وابسته نیست. [1]Team APIوقتی از API صحبت می‌کنیم معمولاً به Interfaceهای نرم‌افزاری فکر می‌کنیم. اما Team API گسترده‌تر است.از دید کتاب، هر چیزی که یک تیم دیگر برای تعامل مؤثر با یک تیم نیاز دارد، می‌تواند بخشی از Team API باشد؛ از Software API و Documentation گرفته تا Onboarding، روش‌های ارتباطی، Chat Channelها، انتظارات و حتی نحوه‌ درخواست کمک. [1]Software API = How software talks to softwareTeam API = How one team interacts with another teamFigure 3.3: Typical vs. Team-First Software Subsystem Boundariesبنابراین، در Part I به این پرداخته شد که Org Chart واقعیت کامل سازمان نیست، ساختار ارتباطی تیم‌ها روی معماری اثر دارد و معماری باید با ظرفیت تیم‌ها سازگار باشد. [1]Team Topologies را می‌توان مکملی برای دیدگاه Allocation Structure در Software Architecture in Practice دانست، نه جایگزینی برای آن؛ چرا که Bass بیشتر توضیح می‌دهد معماری چگونه با ساختارها و Quality Attributeها قابل فهم و ارزیابی است، در صورتی که Team Topologies نشان می‌دهد ساختار تیم‌ها، مسئولیت‌ها و ارتباطات آن‌ها چگونه می‌تواند روی همان معماری اثر بگذارد.Part II — Team Topologies That Work for Flowچگونه تیم‌ها و مرزهای آن‌ها را برای جریان بهتر ارزش طراحی کنیم؟Part II به سه سؤال عملی‌تر پاسخ می‌دهد:تیم‌ها را چگونه طراحی کنیم؟چه نوع تیم‌هایی داشته باشیم؟مرز مسئولیت تیم‌ها و مرزهای نرم‌افزار را کجا قرار دهیم؟Chapter 4 — Static Team Topologiesتیم‌ها نباید صرفاً در پاسخ به مشکلات لحظه‌ای و به شکل تصادفی ایجاد شوند. نویسندگان برای ساختارهای تیمی‌ای که آگاهانه برای یک Context مشخص طراحی شده‌اند، اصطلاح Team Topologies را به کار می‌برند. در اینجا واژه‌ Static به معنای همیشگی و غیرقابل‌تغییر نیست؛ منظور ساختاری است که برای یک سازمان و یک مقطع زمانی مشخص مناسب است و می‌تواند بعداً تکامل پیدا کند. این نکته مهم است، چون یکی از اصول اساسی کتاب این است که سازمان نباید یک بار Team Structure را طراحی کند و سپس برای همیشه همان ساختار را حفظ کند.دو Anti-Pattern مهم در طراحی تیمAnti-Pattern به رویکردی گفته می‌شود که در ظاهر می‌تواند منطقی به نظر برسد، اما در عمل معمولاً مشکلات تکرارشونده‌ای ایجاد می‌کند.1. Ad Hoc Team DesignAd Hoc Team Design یعنی تیم‌ها را بدون یک نگاه جامع به کل سازمان و صرفاً در پاسخ به یک نیاز فوری ایجاد کنیم.برای مثال، فرض کنید یک مشکل جدی در Database رخ داده است. یک واکنش ممکن این است که فوراً یک DBA Team بسازیم. یا اگر فرآیند Deployment دشوار است، یک DevOps Team مستقل ایجاد کنیم. چنین تصمیم‌هایی ممکن است در کوتاه‌مدت منطقی به نظر برسند، اما اگر روابط میان تیم جدید و سایر تیم‌ها بررسی نشود، همین Team می‌تواند به یک Dependency یا Bottleneck جدید تبدیل شود. در نتیجه، حل یک مشکل محلی ممکن است مشکل جدیدی در سطح سیستم ایجاد کند.2. Shuffling Team MembersShuffling Team Members یعنی افراد را برای Projectها یا Initiativeهای مختلف دائماً جابه‌جا کنیم و تیم‌ها را پس از پایان هر پروژه منحل یا بازسازی کنیم. این روش ممکن است در ظاهر انعطاف‌پذیری زیادی ایجاد کند، اما هزینه‌هایی دارد که اغلب دیده نمی‌شوند؛ از جمله تشکیل دوباره‌ی تیم، از دست رفتن دانش، Context Switching، کاهش Cohesion، نیاز به ایجاد دوباره‌ی اعتماد و روش کار مشترک و زمان لازم برای آشنایی اعضا با Context جدید.بنابراین یک مهندس با انتقال از یک تیم به تیم دیگر الزاماً همان عملکرد قبلی را ندارد، زیرا عملکرد تیم فقط به مهارت‌های فردی وابسته نیست و از روابط، Context و نحوه‌ همکاری اعضا نیز تأثیر می‌گیرد.Design for Flow of Changeهدف طراحی تیم‌ها فقط این نیست که ساختار سازمانی مرتب‌تر شود. هدف اصلی باید Flow of Change باشد؛ یعنی حرکت تغییر از ایده تا نرم افزار قابل استفاده با کمترین اصطکاک، انتظار و Handoff.Feature TeamsFeature Team تیمی چندتخصصی است که می‌تواند یک Feature را به‌ صورت End-to-End تحویل دهد، به جای اینکه Feature بین تیم‌های تخصصی متعدد جابه‌جا شود.اما کتاب یک نکته‌ی مهم را هم مطرح می‌کند: Feature Team بدون Engineering Maturity کافی ممکن است مشکل‌ساز شود. اگر تیم مجبور باشد برای یک Feature به چند Codebase متعلق به Component Teamهای مختلف دست بزند، Engineering Discipline پایین می‌تواند باعث افزایش Technical Debt و کاهش اعتماد میان تیم‌ها شود. بنابراین Feature Team یک نسخه‌ی جادویی برای همه‌ی سازمان‌ها نیست و میزان موفقیت آن به Context و بلوغ سازمان وابسته است.Product TeamsProduct Team تیمی است که مسئول مجموعه‌ای از قابلیت‌های یک Product است و هدفش ارائه‌ ارزش End-to-End به کاربران است. با این حال، Product Team حتی با وجود Ownership بالا همچنان ممکن است به Infrastructure، Test Environment، Build Systems یا Delivery Pipeline وابسته باشد.Non-Blocking Dependenciesهر Dependency الزاماً بد نیست. Dependency زمانی به مشکل جدی تبدیل می‌شود که باعث شود تیم برای ادامه‌ کار منتظر تیم دیگری بماند.Cloud Teams و Infrastructureدر سازمان‌های مدرن، Cloud و Infrastructure نقش مهمی دارند، اما کتاب نسبت به ساخت تیم‌های تخصصی‌ای که در مسیر اصلی تحویل قرار می‌گیرند هشدار می‌دهد. اگر یک Cloud یا Infrastructure Team برای هر Deployment یا تغییر محیط باید به‌صورت دستی وارد فرآیند شود، این تیم به بخشی از Delivery Path تبدیل می‌شود و Flow را کند می‌کند. راه‌حل، تا حد امکان، ارائه‌ی Capabilityهای زیرساختی به‌صورت Self-Service است؛ یعنی تیم مصرف‌کننده بتواند از آن‌ها بدون هماهنگی دائمی با تیم ارائه‌دهنده استفاده کند.SRE — Site Reliability EngineeringSRE = Site Reliability Engineeringکتاب SRE را نیز به‌عنوان یکی از الگوهای مرتبط با ساختار تیمی بررسی می‌کند و نکته‌ی قابل توجه این است که SRE Team را نوع خاصی از Stream-Aligned Team در نظر می‌گیرد؛ زیرا مسئولیت آن حول Reliability سرویس‌های بزرگ در Production تعریف می‌شود و کار آن نیز با یک جریان مشخص از تغییرات مرتبط است.در Team Topologies، مسئولیت Production تا حد امکان به تیمی که Software را می‌سازد و Evolution آن را دنبال می‌کند نزدیک باقی می‌ماند.Figure 4.3: Relationship between SRE Team and Application Teamانتخاب Topology به Context بستگی دارد و هیچ Topology واحدی برای تمام سازمان‌ها مناسب نیست.کتاب عواملی مانند این موارد را در انتخاب Topology مهم می‌داند: اندازه‌ی سازمان، مقیاس نرم افزار،Technical and Cultural Maturity، میزان Dependency میان تیم‌ها، Engineering Discipline و Wait Time بین تیم‌ها.سازمانی با بلوغ پایین ممکن است هنوز برای رسیدن به تیم‌های کاملاً Autonomous آماده نباشد. در چنین شرایطی، تیم‌های تخصصی‌تر می‌توانند موقتاً قابل قبول باشند، به شرط آن که همکاری میان آن‌ها باعث افزایش Wait Time نشود. با افزایش بلوغ فنی و فرهنگی، امکان استفاده‌ی گسترده‌تر از تیم‌های Autonomous و Stream-Aligned فراهم می‌شود.بنابراین Topology باید با Context سازگار باشد.Splitting ResponsibilitiesChapter 5 — The Four Fundamental Team Topologiesدر بسیاری از سازمان‌ها با تعداد زیادی Team Type و Team Name متفاوت مواجه می‌شویم. مشکل این است که این تنوع زیاد باعث می‌شود پاسخ به سؤال‌هایی مثل &#34;چه تیمی چه کاری انجام می‌دهد؟&#34; دشوار شود. راه‌حل Team Topologies کاهش این تنوع به چهار Fundamental Team Topologies است: Stream-aligned Team، Enabling Team، Complicated-subsystem Team و Platform.Figure 5.1: The Four Fundamental Team TopologiesStream-Aligned TeamStream چیست؟Stream به جریان پیوسته‌ای از کار گفته می‌شود که معمولاً با یک Business Domain یا Organizational Capability هم‌راستا است.بر این اساس، Stream-Aligned Team، تیمی است که با یک Stream of Change هم‌راستا است و هدف اصلی آن حفظ جریان پیوسته‌ی ارزش است.این تیم باید تا حد امکان Cross-functional و Long-lived باشد، Ownership روشن داشته باشد، بتواند End-to-End کار کند، کمترین Handoff را داشته باشد و بدون انتظار دائمی از تیم‌های دیگر Software را تحویل دهد.کتاب برای یک Stream-aligned Team مؤثر، Delivery پیوسته‌ی Featureها، Course Correction سریع بر اساس Feedback و حداقل Handoff با تیم‌های دیگر را از رفتارهای مورد انتظار می‌داند.چرا Stream-Aligned؟همه‌ی سیستم‌های نرم‌افزاری الزاماً یک Product یا Feature مشخص ندارند. در یک سیستم IoT، یک سرویس عمومی یا یک محیط چندکاناله ممکن است تعریف Product مبهم باشد، اما مفهوم Stream of Change همچنان قابل استفاده است.همچنین در یک سازمان بهینه‌شده برای Flow، بیشتر تیم‌ها باید Stream-Aligned باشند و سایر Team Topologyها عمدتاً برای کمک به آن‌ها شکل می‌گیرند.به بیان ساده: &#34;بیشتر تیم‌ها باید مستقیماً به جریان ارزش متصل باشند و تعداد تیم‌های پشتیبان باید محدود و هدفمند باقی بماند.&#34;Enabling TeamEnabling Team تیمی است که به تیم‌های دیگر کمک می‌کند یک Capability جدید را یاد بگیرند یا یک Technology، Practice یا Approach جدید را Adopt کنند.Enabling Team به‌جای اینکه این کار را برای همیشه بر عهده بگیرد، باید Capability را به تیم مقصد منتقل کند. بنابراین هدف آن ایجاد Dependency دائمی نیست؛ برعکس، باید با انتقال Capability، Dependency را کاهش دهد.Enabling Team و Community of PracticeCommunity of Practice شبکه‌ای گسترده‌تر از افراد علاقه‌مند از تیم‌های مختلف است که برای Sharing Knowledge و بهبود Practiceها با یکدیگر در ارتباط‌اند. در مقابل، Enabling Team یک تیم تخصصی متمرکز است که برای یک تیم یا تعداد محدودی تیم، فعالیت‌های Enablement را به‌صورت جدی دنبال می‌کند. این دو می‌توانند در کنار یکدیگر وجود داشته باشند.Complicated-subsystem TeamComplicated-subsystem Team برای بخشی از سیستم ایجاد می‌شود که به Specialist Knowledge عمیق نیاز دارد؛ به‌گونه‌ای که انتظار اینکه همه‌ی Stream-aligned Teams خودشان این تخصص را در اختیار داشته باشند، منطقی یا اقتصادی نیست. هدف این تیم، Offload کردن پیچیدگی تخصصی از Stream-aligned Teams است.Complicated-subsystem Team با Component Team چه تفاوتی دارد؟در یک سازمان سنتی ممکن است بگوییم: &#34;این Component بین چند سیستم مشترک است، بنابراین یک Component Team بسازیم&#34;، اما Team Topologies می‌گوید Shared بودن به‌تنهایی دلیل کافی نیست.&#34;آیا این Subsystem آن‌قدر پیچیده و تخصصی است که Cognitive Load تیم‌های Stream-aligned را بیش از ظرفیت آن‌ها افزایش می‌دهد؟&#34;اگر پاسخ منفی باشد، ایجاد یک Team تخصصی جداگانه ممکن است خودش باعث افزایش Dependency شود. کتاب تأکید می‌کند که تصمیم برای ایجاد Complicated-subsystem Team باید بر اساس Cognitive Load گرفته شود، نه صرفاً Shared بودن Component.Platform Teamهدف Platform، توانمند کردن Stream-aligned Teams برای تحویل Software با Autonomy بیشتر است. Stream-aligned Team همچنان Ownership ساختن، اجرا و رفع مشکلات Application خود را در Production حفظ می‌کند؛ Platform قرار نیست این مسئولیت را از آن بگیرد.Platform as a ProductPlatform نباید صرفاً یک مجموعه ابزار زیرساختی باشد که توسعه‌دهندگان مجبورند خودشان پیچیدگی آن را مدیریت کنند، بلکه باید مانند یک Product یا Service مدیریت شود، به نیازهای کاربران داخلی خود توجه کند و برای تیم‌های مصرف‌کننده ارزش ایجاد کند، نه اینکه مصرف‌کنندگان را مجبور کند خودشان را با پیچیدگی Platform تطبیق دهند.Self-Serviceیعنی یک Stream-aligned Team بتواند Capability مورد نیاز خود را بدون ایجاد یک Ticket یا هماهنگی دستی با تیم Platform دریافت و استفاده کند. در این مدل Platform واقعاً Dependency را حذف نمی‌کند؛ بلکه آن را Non-Blocking می‌کند.Figure 5.2: Platform Composed of Several Fundamental Team TopologiesTVP = Thinnest Viable Platformیعنی کوچک‌ترین Platformی که Capability کافی برای ساده‌تر و سریع‌تر کردن Delivery تیم‌های مصرف‌کننده را فراهم می‌کند.Platform باید Complexity را از تیم بگیرد، نه اینکه Complexity جدیدی به آن بدهد.Platform Grouping و Fractal Organizationکتاب توضیح می‌دهد که در سازمان‌های بزرگ‌تر، معمولاً یک Platform را نمی‌توان با یک تیم کوچک ساخت و اداره کرد. بنابراین Platform ممکن است از چند Team تشکیل شود.این مفهوم به Fractal Organization مربوط است؛ یعنی الگوهای مشابه Team Topologies می‌توانند در چند سطح یا Zoom Level تکرار شوند. وقتی از بیرون به Platform نگاه می‌کنیم، یک Capability واحد می‌بینیم؛ اما وقتی داخل آن را بررسی کنیم، ممکن است چند Stream-aligned، Enabling، Complicated-subsystem یا Platform Team دیگر ببینیم.Chapter 6 — Choose Team-First Boundariesمرز این تیم‌ها و نرم افزار مسئول آن‌ها را کجا قرار دهیم؟ایده‌ی اصلی این است که Software Boundary نباید فقط بر اساس ساختار فنی موجود انتخاب شود؛ بلکه باید با Responsibility، Ownership و Cognitive Capacity تیم نیز سازگار باشد.Hidden Monolithsکتاب هشدار می‌دهد که حتی یک سیستم ظاهراً Distributed یا Microservice-based نیز ممکن است در عمل همچنان به‌شدت یکپارچه باشد.نمونه‌هایی از این وضعیت عبارت‌اند از:Application Monolith: یک Application بزرگ و یکپارچه؛Joined-at-the-Database Monolith: چند Service که به یک Database مشترک وابستگی شدید دارند؛Monolithic Rebuild و Monolithic Release: جایی که Build یا Release همچنان به‌صورت یکپارچه انجام می‌شود؛Monolithic Model: تحمیل یک Model مشترک بر Domainهای متفاوت؛Monolithic Thinking: تلاش برای اعمال یک Technology، استاندارد یا روش واحد بر همه‌ی تیم‌ها بدون توجه به Context.بنابراین داشتن چند Service به‌تنهایی به معنای استقلال معماری نیست. اگر Serviceها همچنان به Shared Database، Release مشترک یا Coordination گسترده وابسته باشند، ممکن است با یک Distributed Monolith روبه‌رو باشیم.Fracture Planesبرای انتخاب Boundary مناسب، کتاب مفهوم Fracture Plane را معرفی می‌کند؛ یعنی یک Seam یا نقطه‌ی طبیعی که Software می‌تواند در آن به بخش‌های مستقل‌تر تقسیم شود.یکی از مهم‌ترین گزینه‌ها Business Domain / Bounded Context است.هر Splitای لزوماً مفید نیستجدا کردن Software می‌تواند پیامدهایی مانند Data Duplication، کاهش Consistency، آسیب به UX یکپارچه و افزایش Complexity سیستم‌های توزیع‌شده داشته باشد؛ بنابراین هدف، Distributed کردن سیستم نیست؛ هدف پیدا کردن مرزی است که Cognitive Load را مدیریت کند، Ownership را شفاف کند، Dependencyهای غیرضروری را کاهش دهد و Team Autonomy را افزایش دهد.چرا Team-First Boundary یک موضوع معماری است؟اگر Software را به Serviceهای مستقل تقسیم کنیم اما برای تغییر هر Service همچنان به چند Team دیگر وابسته باشیم، Architectural Decomposition در عمل استقلال مورد انتظار را ایجاد نکرده است.بنابراین Software Boundary و Team Boundary باید تا حد امکان با یکدیگر سازگار باشند.Figure 6.1: Mobile, Cloud, and IoT Technology Fracture Plane ScenarioPart III — Evolving Team Interactions for Innovation and Rapid Deliveryحتی اگر تیم‌ها و مرزهای آن‌ها را درست انتخاب کرده باشیم، چگونه باید این تیم‌ها با یکدیگر تعامل کنند و چه زمانی باید این تعاملات یا حتی خود ساختار تیم‌ها را تغییر دهیم؟کتاب در این بخش تأکید می‌کند که داشتن چهار نوع تیم بنیادی به‌تنهایی برای دستیابی به اثربخشی بالا کافی نیست. باید مشخص شود تیم‌ها چه نوع تعاملی با یکدیگر دارند و این تعاملات در طول زمان چگونه تغییر می‌کنند.Team Interaction ModeTeam Interaction Mode یعنی الگوی مشخصی که تعیین می‌کند دو تیم چگونه باید با یکدیگر کار کنند.کتاب سه Essential Team Interaction Modes معرفی می‌کند: Collaboration، X-as-a-Service و Facilitating. نویسندگان این سه Mode را به‌عنوان روش‌های اصلی و شفاف برای تعریف تعامل میان تیم‌های سازنده‌ی سیستم‌های نرم‌افزاری معرفی می‌کنند.Figure 7.2: The Three Team Interaction ModesFigure 7.3: Team Interaction Modes ScenarioDevExDevEx مخفف Developer Experience است؛ یعنی تجربه‌ توسعه‌دهندگان هنگام استفاده از یک Platform، ابزار یا Service. این مفهوم به‌ویژه در X-as-a-Service اهمیت پیدا می‌کند، زیرا Service باید برای مصرف‌کننده ساده، قابل فهم، قابل تست و قابل استفاده باشد. کتاب به‌طور مشخص بر اهمیت تجربه‌ی استفاده از Service و کیفیت Documentation تأکید می‌کند.BAUBAU مخفف Business as Usual است و در کتاب برای اشاره به تیم‌ها یا فعالیت‌هایی به کار می‌رود که مسئول نگهداری و اجرای سیستم‌های موجود هستند.Organizational SensingOrganizational Sensing به توانایی سازمان برای دریافت Signal از محیط و عملکرد خودش و استفاده از آن اطلاعات برای اصلاح Team Structure، Interaction و شیوه‌ی کار اشاره دارد.Self-SteeringSelf-Steering یعنی سازمان بتواند بر اساس Signals و Feedbackهایی که از محیط دریافت می‌کند، مسیر و ساختار خودش را به‌صورت مستمر اصلاح کند.Chapter 7 — Team Interaction Modesصرفاً قرار دادن تیم‌ها در کنار هم کافی نیست.حتی اگر Team Structure مناسب باشد، Interaction نامناسب می‌تواند باعث افزایش Coordination، افزایش Cognitive Load، مبهم شدن مسئولیت‌ها و کاهش Flow شود.به همین دلیل، کتاب سه Interaction Mode اصلی معرفی می‌کند که هدف آن‌ها ایجاد یک زبان مشترک برای مشخص کردن نحوه‌ی همکاری تیم‌هاست.CollaborationCollaboration یعنی دو تیم برای رسیدن به یک هدف مشترک، به‌صورت نزدیک با یکدیگر کار کنند. کتاب این Mode را به‌ویژه برای شرایطی مناسب می‌داند که Discovery و Adaptability اهمیت زیادی دارند؛ مثلاً زمانی که یک Technology جدید، روش جدید یا مسئله‌ای ناشناخته در حال بررسی است. در چنین شرایطی، فرض کردن یک Interface کاملاً تثبیت‌شده از همان ابتدا معمولاً تصمیم مناسبی نیست. دو تیم ابتدا باید بتوانند با یکدیگر یاد بگیرند و شکل مناسب راه‌حل را پیدا کنند.مزیت اصلی Collaboration این است که هزینه‌ی Handoff را در مرحله‌ی Discovery کاهش می‌دهد.تیم‌ها می‌توانند Knowledge خود را کنار هم قرار دهند، Prototype بسازند، رفتار فناوری را بررسی کنند و راه‌حل‌های مختلف را سریع‌تر امتحان کنند. کتاب Collaboration را دقیقاً به همین دلیل، یک Driver مهم برای Innovation و Rapid Discovery معرفی می‌کند.Collaboration اگرچه برای Discovery بسیار مفید است، اما رایگان نیست. هرچه Interaction میان دو تیم بیشتر شود، Coordination و Context Sharing نیز بیشتر می‌شود. بنابراین Collaboration می‌تواند Boundaryها را مبهم کند، Coordination را افزایش دهد، Cognitive Load را بالا ببرد و در صورت تداوم بیش از حد، Flow را کاهش دهد. به همین دلیل، کتاب Collaboration را عموماً برای Discovery مناسب می‌داند نه به‌عنوان بهترین مدل برای Delivery پایدار.&#34;High Interaction and Mutual Respect.&#34;X-as-a-Serviceدر این حالت، یک تیم چیزی را در قالب یک Service در اختیار تیم دیگر قرار می‌دهد و Team مصرف‌کننده برای استفاده از آن به Collaboration گسترده نیاز ندارد.&#34;consuming or providing something with minimal collaboration&#34;یعنی مصرف یا ارائه‌ چیزی با حداقل همکاری.عبارت X عمداً عمومی است و می‌تواند موارد مختلفی را شامل شود. از جمله API، Platform Service، Code Library، Infrastructure Service و Software Product.چه زمانی X-as-a-Service مناسب است؟این Mode زمانی مناسب‌تر است که مسئله نسبتاً شناخته‌شده باشد، Boundary مشخص شده باشد، API یا Interface پایدار شده باشد، رفتار Service قابل پیش‌بینی باشد و هدف اصلی Delivery سریع و قابل پیش‌بینی باشد.از مزایای اصلی این Mode، واضح‌تر شدن Ownership و Responsibility، کاهش Detail Sharing و Lower Cognitive Load است.X-as-a-Service و Developer Experienceدر X-as-a-Service، یک تیم Capability یا Service خود را با یک Interface مشخص در اختیار تیم دیگری قرار می‌دهد تا مصرف‌کننده بتواند با حداقل Collaboration از آن استفاده کند. برای موفق بودن این تقابل، Developer Experience (DevEx) اهمیت زیادی دارد؛ Service باید ساده برای استفاده، قابل تست و به‌خوبی مستند باشد و Provider نیز مسئولیت Versioning و Compatibility آن را مدیریت کند. در نتیجه، X-as-a-Service زمانی مناسب‌تر است که Boundary و API نسبتاً تثبیت شده باشند. اگر Interface نامناسب باشد، نیاز به سؤال و هماهنگی افزایش پیدا می‌کند و در نهایت Flow کاهش می‌یابد.Facilitatingدر این حالت، یک تیم به تیم دیگری کمک می‌کند تا یک Capability جدید کسب کند، یک Technology را یاد بگیرد یا یک Impediment را برطرف کند. این Mode ارتباط نزدیکی با Enabling Team دارد و هدف آن ایجاد Capability Transfer و افزایش استقلال تیم مقصد است، نه ایجاد یک Dependency دائمی.&#34;Help and Be Helped&#34;این Interactionها با چهار Fundamental Team Topologies نیز ارتباط دارند؛ برای مثال Enabling Team بیشتر از Facilitating استفاده می‌کند، در حالی که Platform و Complicated-subsystem Team معمولاً قابلیت‌های خود را به‌صورت X-as-a-Service ارائه می‌کنند.Chapter 8 — Evolve Team Structures with Organizational Sensingچه زمانی باید این Interactionها و حتی خود ساختار تیم‌ها را تغییر دهیم؟ایده‌ی اصلی این فصل این است که Team Topologies نباید یک طراحی ثابت و یک‌باره باشد. با تغییر Business، Technology، Product، Team Capability و میزان Uncertainty، ساختار مناسب نیز می‌تواند تغییر کند.Evolution of Team Interactionsیکی از الگوهای مهم کتاب، تکامل رابطه از Collaboration به X-as-a-Service است. در ابتدای یک مسئله یا Technology جدید، Uncertainty زیاد است و Collaboration به تیم‌ها کمک می‌کند با یکدیگر یاد بگیرند. با تثبیت دانش و Boundary، نیاز به تعامل مستقیم کمتر می‌شود و رابطه می‌تواند به یک Service پایدار تبدیل شود.کتاب این روند را با چهار مرحله‌ی Explore، Exploit، Sustain و Retire نیز مرتبط می‌کند:Explore: تمرکز بر Discovery و LearningExploit: تمرکز بر Delivery قابل پیش‌بینیSustain: حفظ، اجرا و تکامل پایدارRetire: خروج یا بازطراحی Capability یا Serviceای که دیگر ارزش کافی ندارد.در یک سازمان بزرگ نیز ممکن است بخش‌های مختلف هم‌زمان در این مراحل متفاوت باشند؛ بنابراین Interaction Modeها نیز می‌توانند در بخش‌های مختلف سازمان متفاوت باشند.Evolution Triggersتغییر Team Topology باید بر اساس نشانه‌های واقعی انجام شود. کتاب مواردی مانند این‌ها را از مهم‌ترین Evolution Triggerها می‌داند:- Software دیگر در Cognitive Capacity یک تیم نمی‌گنجد.- Delivery Cadence کاهش پیدا کرده است.- تعداد زیادی Business Service به یک مجموعه‌ی مرکزی از Services وابسته شده‌اند.- Dependencyها یا Coordination بیش از حد شده‌اند.این نشانه‌ها می‌توانند بیانگر این باشند که Boundary، Ownership یا Interaction فعلی دیگر مناسب نیست و باید بازنگری شود.Organizational Sensingیعنی سازمان به‌صورت مستمر از محیط و عملکرد خود Signal دریافت کند و بر اساس آن درباره‌ی Team Structure و Interaction تصمیم بگیرد.این Signalها می‌توانند از منابعی مانند Production، User Behaviour، Delivery Performance، Team Friction، Business Changes و Technology Changes به‌ دست آیند.در این نگاه، سازمان صرفاً یک ساختار ثابت نیست؛ بلکه باید بتواند بر اساس Feedback خود را تنظیم کند و به یک Self-Steering Organization نزدیک شود.ProductionProduction فقط محل اجرای Software نیست. Production می‌تواند منبع مهمی از Feedback باشد که نشان می‌دهد کاربران واقعاً چگونه از سیستم استفاده می‌کنند، کجا Failure یا Performance Problem وجود دارد، چه تصمیم‌هایی در عمل موفق بوده‌اند و کدام بخش‌های Architecture یا Team Structure نیاز به تغییر دارند.تیمی که Software را می‌سازد باید تا حد امکان در Running و Operation آن نیز درگیر باشد. در غیر این صورت، ارتباط میان Design، Development و Production قطع می‌شود.نقش Architect در Evolutionدر این مدل، Software Architect فقط طراح ساختار فنی نیست. Architect باید رابطه‌ی میان Architecture، Team Boundaries، Team APIs و Interaction Modes را نیز در نظر بگیرد و از Feedbackهای واقعی برای اصلاح تصمیم‌های معماری و سازمانی استفاده کند.بنابراین Team Topology یک پاسخ نهایی و ثابت نیست. سازمان باید دائماً شرایط خود را Sense کند، Evolution Triggerها را بشناسد و در صورت نیاز Team Structure، Boundaryها و Interaction Modeها را تغییر دهد.Figure 9.1: Core Ideas of Team Topologiesجمع‌بندیکتاب Team Topologies نگاه به Software Delivery را از سطح صرفاً فنی فراتر می‌برد و نشان می‌دهد که معماری نرم‌افزار، ساختار تیم‌ها و نحوه‌ ارتباط آن‌ها به‌شدت به یکدیگر وابسته‌اند.در نهایت، می‌توان کل کتاب را در این چرخه خلاصه کرد:Cycle of Team Topologiesبنابراین پیام اصلی کتاب این نیست که چهار نوع تیم بسازیم؛ بلکه این است که تیم‌ها، مرزهای مسئولیت، نحوه‌ی تعامل و معماری نرم‌افزار باید به‌عنوان یک Sociotechnical System در کنار یکدیگر طراحی و دائماً تکامل داده شوند.[1] Matthew Skelton, Manuel Pais, Team Topologies: Organizing Business and Technology for Fast Flow of Value, Second Edition, IT Revolution Press, 2025[2] Len Bass, Paul Clements, Rick Kazman, Software Architecture in Practice, Fourth Edition, Addison-Wesley Professional, 2021[3] Sadegh Aliakbary, Software Architecture Course, Course Slidesاين مطلب، بخشی از تمرين ها و پروژه درس معماری نرم‌افزار دانشگاه شهيد بهشتی است.</description><category>Maedeh Zarei</category><author>Maedeh Zarei</author><pubDate>Wed, 12 Aug 2026 00:03:02 +0330</pubDate></item><item><title>مروری بر 5 سخنرانی برتر معماری نرم‌افزار؛ از Evolutionary Architecture تا Data Mesh و Microservices</title><link>https://virgool.ir/@MaedehZarei/مروری-بر-5-سخنرانی-برتر-معماری-نرم-افزار-از-evolutionary-architecture-تا-data-mesh-و-microservices-xqp8ypw7rmrr</link><description>مروری بر 5 سخنرانی برتر معماری نرمافزار؛ از Evolutionary Architecture تا Data Mesh و Microservicesمعماری نرم افزار حوزه ای است که دائماً تحت تأثیر تجربه های واقعی صنعت، فناوری های جدید و تغییر شیوه های توسعه قرار می گیرد. به همین دلیل، سخنرانی های کنفرانس هایی مانند GOTO یکی از بهترین منابع برای آشنایی با دیدگاه های معماران و مهندسان باتجربه به شمار می روند؛ افرادی که بسیاری از ایده های مطرح شده را در پروژه های واقعی و در مقیاس بزرگ به کار گرفته اند.در این مطلب، مروری بر پنج سخنرانی مرتبط با معماری نرم افزار ارائه شده و در هر بخش، تلاش شده ضمن بیان ایده های اصلی، به مثال های مهم، مفاهیم کلیدی و برداشت شخصی خود نیز اشاره کرده تا ارتباط این مباحث با درس معماری نرم افزار روشن تر شود.Data: The Land DevOps Forgot - Michael Nygard - GOTO 2024Data: The Land DevOps ForgotMichael NygardGOTO 2024https://www.youtube.com/watch?v=SfIvrtDsE3QMichael Nygard در این سخنرانی سراغ بخشی از مهندسی نرم افزار می رود که معمولاً در گفتگوهای DevOps کمتر از آن حرف زده می شود: داده. پیام اصلی او این است که اگرچه DevOps توانسته چرخه توسعه و استقرار نرم افزار را متحول کند، اما همان منطق و همان ابزار را نمی توان بدون تغییر، مستقیماً به دنیای داده و تحلیل منتقل کرد. او با مثال های واقعی از Nubank نشان می دهد که سیستم های داده ای در مقیاس بزرگ، منطق عملیاتی متفاوتی دارند؛ از تأخیرهای طولانی در پردازش گرفته تا هزینه ی بالای تغییر؛ همین تفاوت ها باعث می شود که معماری داده نیازمند نگاه مستقل باشد.یکی از نکات مهم سخنرانی، تفاوت بین دنیای تراکنشی و دنیای تحلیلی است. در سیستم های تراکنشی، تغییرات معمولاً در چند دقیقه یا چند ثانیه اثر می گذارند و خطاها سریع دیده می شوند، ولی در سیستم های تحلیلی، یک تغییر ممکن است ساعت ها یا حتی روزها بعد خودش را نشان دهد. این فاصلهی زمانی، هم اشکال زدایی را سخت تر می کند و هم هزینه ی تصمیم های معماری را بالا می برد. به همین دلیل نایگارد تأکید می کند که مدیریت داده فقط یک مسئله ی فنی نیست، بلکه به سازمان، مالکیت، شفافیت و اعتماد هم وابسته است.مفهوم Data Mesh در این سخنرانی به خوبی برجسته می شود. او توضیح می دهد که داده باید مانند یک محصول دیده شود، نه صرفاً یک خروجی خام از سیستم ها. وقتی داده محصول است، باید مالک داشته باشد، کیفیتش قابل سنجش باشد، مسیر تولیدش مشخص باشد و مصرف کننده بتواند به آن اعتماد کند. این دیدگاه برای من بسیار مهم بود، چون نشان می دهد که در معماری نرم افزار، مرزها و مسئولیت ها به اندازه ی انتخاب فناوری اهمیت دارند. اگر تیم ها فقط تولیدکننده داده باشند و هیچ حس مالکیتی نسبت به کیفیت و مصرف آن نداشته باشند، پیچیدگی سیستم به مرور از کنترل خارج می شود.از منظر درس معماری نرم افزار، این سخنرانی یک نمونه ی روشن از معماری socio-technical است؛ یعنی جایی که طراحی فنی و طراحی سازمانی به هم گره خورده اند. Data Mesh بدون تغییر در مدل همکاری تیم ها، ساختار مالکیت، و ساز و کارهای governance عملاً کار نمی کند. بنابراین معماری موفق فقط در کد تعریف نمی شود، بلکه در نحوهی هماهنگی آدم ها، تیم ها و تصمیم ها هم شکل میگیرد.نقطه قوت این سخنرانی در واقع گرایی آن است. نایگارد ایده هایش را در قالب تجربه ی عملی و واقعی و هزینه های ملموس توضیح می دهد. پیام اصلی سخنرانی بسیار روشن است: اگر داده را جدی نگیریم، حتی بهترین معماری نرم افزار هم در عمل شکننده خواهد بود.Tidy First? A Daily Exercise in Empirical Design - Kent Beck - GOTO 2024Tidy First? A Daily Exercise in Empirical DesignKent BeckGOTO 2024https://www.youtube.com/watch?v=Saaz6D1azlUKent Beck در این سخنرانی، معماری و طراحی نرم افزار را از زاویه ای بسیار انسانی و در عین حال دقیق توضیح می دهد. او بحث را از یک سؤال ساده شروع می کند: وقتی با یک تکه کد نامرتب رو به رو می شویم، آیا باید اول آن را مرتب کنیم یا مستقیم سراغ تغییر رفتار برویم؟ همین سؤال، کوچکترین واحد تصمیم گیری در طراحی نرم افزار است. عنوان Tidy First دقیقاً به همین لحظه اشاره دارد؛ لحظه ای که باید تصمیم بگیریم قبل از اعمال feature، ساختار را بهتر کنیم یا نه.آنچه این سخنرانی بسیار جذاب است، این است که یک طراحی نرم افزار را نه یک فعالیت انتزاعی، بلکه یک کنش روزمره و بسیار عملی نشان می دهد. او می گوید طراحی نرم افزار در اصل برای تغییر دادن نرم افزار است؛ اگر قرار نیست چیزی تغییر کند، اهمیت طراحی هم بسیار کمتر می شود؛ اما چون نرم افزار دائماً در حال تغییر است، ساختار داخلی آن تعیین می کند که این تغییر چقدر آسان، چقدر پرهزینه و چقدر امن خواهد بود. اینجا ایده ی technical debt دوباره معنا پیدا می کند: مشکل فقط این نیست که کد بد نوشته شده، بلکه این است که ساختار بد، هزینه ی تغییر را به مرور بالا می برد.بک در ادامه توضیح می دهد که چرا سرمایه گذاری در ساختار معمولاً کمتر از چیزی است که باید باشد. featureها قابل دیدن هستند، اما ساختار نه. کاربران و مدیران نتیجه ی feature را میبینند، اما هزینه ی پنهان ساختار را معمولاً وقتی می فهمند که دیگر دیر شده است، توسعه کند شده، defectها بیشتر شده و تیم برای هر تغییر کوچک، باید مسیر طولانی تری را طی کند.این بخش از سخنرانی به خوبی نشان می دهد که معماری صرفاً به زیبایی کد یا اصول انتزاعی مربوط نیست، بلکه مستقیماً به اقتصاد تغییر در نرم افزار مرتبط است.مثال های او دربارهی payroll calculator و تجربه ی ساخت دو نسخه ی موازی از یک قابلیت، خیلی خوب این مفهوم را جا می اندازد که گاهی یک تصمیم ساختاری در آینده فرصت های جدیدی ایجاد می کند. یعنی یک refactoring یا ساده سازی ساختار، بعداً featureهایی را ممکن می کند که قبلاً بسیار پرهزینه بودند. این همان چیزی است که بک آن را نوعی بازده غیرخطی در نرم افزار می داند. این نگاه نشان می دهد architecture فقط برای جلوگیری از مشکل نیست؛ گاهی برای خلق فرصت های جدید هم هست.نکتهی مهم دیگر، نگاه او به رابطه ی انسانی در طراحی است. بک به صراحت می گوید که software design فقط دربارهی کد نیست، بلکه درباره ی رابطه ی انسان ها، اعتماد، انگیزه ها و همکاری تیمی هم هست. این موضوع را می توان در سطح architecture هم دید؛ اگر design decisions بدون توجه به social structure گرفته شوند، همانقدر شکست می خورند که یک abstraction بد در کد. در نتیجه، این سخنرانی، یک یادآوری مهم بود که معماری خوب، ترکیبی از reasoning فنی، تجربه ی عملی و درک انسانی است.Microservices, Where Did It All Go Wrong - Ian Cooper - GOTO 2024Microservices, Where Did It All Go WrongIan CooperGOTO 2024https://www.youtube.com/watch?v=j2AQ9eTZ3-0این سخنرانی یکی از دقیقترین و در عین حال انتقادیترین صحبتها دربارهی Microservices است. Ian Cooper با این پیشفرض شروع نمیکند که Microservices بد هستند؛ برعکس، او میپذیرد که این سبک معماری در بسیاری از زمینهها مزایای واقعی دارد. پرسش اصلی او این است که چرا در عمل، خیلی از پیادهسازیهای Microservices بهجای کاهش پیچیدگی، آن را چند برابر کردهاند. پاسخ او ساده نیست، چون از یک خطای رایج شروع میشود: اشتباه گرفتن micro با کوچک بودنِ صرف، و اشتباه گرفتن service با process.نخستین بخش مهم سخنرانی، بازگشت به تعریفهای کلاسیک است. او توضیح میدهد که module، component، service و microservice هر کدام معنای خاص خود را دارند و نمیتوان آنها را بهجای هم استفاده کرد. microservice قرار نیست فقط یک سرویس خیلی کوچک باشد؛ بلکه باید قابل تفکیک، قابل جایگزینی و manageably small باشد. این distinction بسیار مهم است، چون نشان میدهد بسیاری از مشکلات معماری از واژههایی میآیند که در تیمها دقیق تعریف نشدهاند. وقتی مفهوم service به process، container یا pod تقلیل پیدا کند، کل طراحی از ریشه منحرف میشود.کوپر با مثالهای متعدد نشان میدهد که وقتی تعداد سرویسها بیش از حد زیاد شود، هزینهی coordination، latency، observability و deployment بهشدت بالا میرود. او بارها تأکید میکند که زیاد کردن تعداد سرویسها لزوماً باعث loose coupling نمیشود؛ در بسیاری از موارد، نتیجهی برعکس دارد: cohesion پایین میآید، coupling واقعی بیشتر میشود و هر change کوچک به shotgun surgery تبدیل میشود. رایجترین تصور دربارهی Microservices دقیقاً همین است که کوچکتر کردن همیشه مفید است، در حالی که او نشان میدهد یک sweet spot وجود دارد و عبور از آن، معماری را بدتر میکند.بخش جالب دیگر، نقد او به استفادهی کورکورانه از Kubernetes و containerization است. او میگوید اگر هر service را صرفاً یک container ببینیم، در واقع از معماری به سمت ابزارمحوری لغزیدهایم. یعنی بهجای اینکه مسئلهی دامنه، استقلال تیم، یا قابلیت تغییر را حل کنیم، فقط زیرساخت را پیچیدهتر کردهایم. این نقد، تفاوت architecture با infrastructure را برجسته میکند. معماری با فرایندهای تجاری، مرزهای دامنه و قابلیت reasoning سروکار دارد، نه فقط با نحوهی اجرای deployment.نقطه قوت سخنرانی این است که هم از تجربهی صنعتی استفاده میکند و هم از مبانی نظری. او بهجای شعار، به تفکیک هزینهها، coupling، cohesion و محدودیتهای واقعی سازمانها برمیگردد.Architecture Isn’t Kubernetes - Diana Montalion - GOTO 2024Architecture Isn’t KubernetesDiana MontalionGOTO 2024https://www.youtube.com/watch?v=v50oJao8W1Yاین سخنرانی از آن صحبتهایی است که در ظاهر دربارهی architecture است، اما در عمق، دربارهی شیوهی تفکر است. Diana Montalion با این جملهی کلیدی شروع میکند که architecture را نباید با Kubernetes، cloud-native tooling یا technology stack اشتباه گرفت. بهنظر او، مشکل بسیاری از سازمانها این است که وقتی از architectural modernization حرف میزنند، در عمل منظورشان صرفاً تعویض ابزارهاست؛ در حالی که معماری واقعی، بیش از هر چیز، به نوع reasoning، الگوی تصمیمگیری و روابط انسانی داخل سازمان وابسته است.یکی از محورهای اصلی سخنرانی، systems thinking است. او توضیح میدهد که تفکر خطی و reductionist برای بخشی از مسائل خوب است، اما برای سیستمهای پیچیده کافی نیست و تأکید میکند که معمار نرمافزار باید بتواند بین تحلیل جزءنگر و نگاه سیستمی جابهجا شود. این ایده بسیار مهم است، چون در معماری مدرن، اغلب وسوسه میشویم مسئله را به تکنولوژی تقلیل دهیم؛ مثلاً فکر کنیم اگر به cloud برویم، اگر از microservices استفاده کنیم، یا اگر Kubernetes داشته باشیم، معماری درست میشود. در حالی که او نشان میدهد ابزار فقط بخشی از مسئله است، نه خود مسئله.نکتهی مهم دیگر، توجه به metacognition است؛ یعنی اینکه معمار نهتنها باید دربارهی سیستم فکر کند، بلکه باید دربارهی شیوهی فکر کردن خودش هم آگاه باشد. او با مثالهایی از fallacyها، straw man، و reactionهای غیرسازنده نشان میدهد که بسیاری از خطاهای معماری، قبل از اینکه در code رخ دهند، در reasoning رخ دادهاند. این دیدگاه بسیار بالغ است، چون معماری را از سطح recommendation دادن دربارهی technology stack بالاتر میبرد و آن را به یک practice مبتنی بر قضاوت، تأمل و تعامل تبدیل میکند.مهمترین پیام سخنرانی این است که architecture یک کار ثابت نیست، بلکه practiceی است که دائماً باید در حال رشد باشد. او میگوید شرایط، تیمها، تکنولوژی و مسئلهها دائماً تغییر میکنند و بنابراین هیچ معماریای برای همیشه تمامشده نیست. این حرف، هم ساده است و هم بسیار عمیق. این سخنرانی یادآوری میکند که معماری بیشتر با uncertainty، trade-off و continuous learning سر و کار دارد.این ویدیو مخاطب را از یک نگاه ابزارمحور بیرون میکشد و دوباره به اصل architecture برمیگرداند: سازمان، تصمیم، رابطه، و توانایی دیدن سیستم بهصورت کلنگر. اگر کسی بخواهد معماری را فقط بهعنوان deployment platform بفهمد، این سخنرانی بهخوبی نشان میدهد که آن نگاه ناقص است.Architecture aspects - evolutionary architecture development - Urs Enzler - 2023Architecture aspects - evolutionary architecture developmentUrs Enzlerhttps://www.youtube.com/watch?v=3yZv6oDfY9Eسخنرانی Urs Enzler دربارهی evolutionary architecture یکی از عملیترین صحبتهایی است که میشود در حوزهی معماری نرمافزار دید. پیام مرکزی او این است که architecture نباید از ابتدا بهصورت یک طرح کامل و نهایی تصور شود؛ بلکه باید در طول زمان، همراه با رشد محصول، تغییر نیازها و بازخورد کاربران تکامل پیدا کند. او با مثالهایی از یک سیستم واقعی نشان میدهد که تصمیمهای معماری معمولاً باید مرحله به مرحله و با در نظر گرفتن اطلاعاتی که در هر مرحله بهدست میآید، گرفته شوند.یکی از نکات قابل توجه سخنرانی، تأکید او بر این است که در شروع یک پروژه، over-engineering خطرناک است. وقتی سیستم هنوز کوچک است، رفتن مستقیم به سمت microservices، layering پیچیده یا abstractionهای سنگین معمولاً بیشتر از اینکه مفید باشد، باعث پیچیدگی زودهنگام میشود. او پیشنهاد میکند که در ابتدا ساده شروع کنیم، اما در عین حال از همان ابتدا طوری تصمیم بگیریم که مسیر تکامل در آینده بسته نشود. این نگاه دقیقاً همان چیزی است که در معماری خوب لازم داریم: سادگی امروز، همراه با قابلیت رشد فردا.بخش مهم دیگر، بحث persistence و storage است. Enzler با مقایسهی CRUD، history-based approaches و event sourcing نشان میدهد که هر انتخاب معماری یک trade-off واقعی دارد. اگر فقط current state را ذخیره کنیم، تغییرات سادهتر میشوند؛ اما اگر تاریخچه مهم باشد، event sourcing میتواند ارزشمندتر باشد. در عین حال، او به درستی هشدار میدهد که event sourcing هم همیشه جواب نیست و snapshot، read model یا cache هر کدام در سناریوی مناسب خود معنا دارند. این، معماری را از حالت شعاری خارج میکند و به یک series of decisions مبتنی بر context تبدیل میکند.موضوع layering و modularization هم در سخنرانی جایگاه مهمی دارد. او میگوید که در ابتدا لازم نیست با microservices شروع کنیم؛ بهتر است اول domain را بفهمیم، بعد subsystems را پیدا کنیم، سپس اگر سیستم رشد کرد، به hexagonal architecture، clean architecture یا در نهایت microservices فکر کنیم. این سیر تکاملی نشان میدهد architecture maturity باید متناسب با maturity خود سیستم باشد. یعنی معماری خوب، معماریای نیست که از روز اول پیچیدهترین شکل را داشته باشد، بلکه معماریای است که در هر مرحله، درستترین سطح از سازماندهی را ارائه میدهد.بنابراین، evolutionary architecture یک رویکرد واقعبینانه، اقتصادی و حرفهای است. بهجای اینکه همه چیز را از ابتدا قطعی و ثابت فرض کنیم، باید سیستم را بهصورت زنده، قابلتغییر و باز به سمت آینده ببینیم. این نگاه، هم با تجربهی صنعتی سازگار است و هم با اصل بنیادین معماری نرمافزار که میگوید: بهترین طراحی، طراحیای است که تغییر را ممکن و ارزان نگه میدارد.Software Architectureمطالعه و بررسی این سخنرانیها نشان میدهد که معماری نرمافزار تنها به انتخاب فناوری یا ابزار محدود نمیشود، بلکه بیش از هر چیز به شیوهی تفکر، تصمیمگیری و مدیریت تغییر وابسته است. با وجود تفاوت موضوعات، همه سخنرانان بر مفاهیمی مانند Evolutionary Architecture، Modularity، Trade-off، کاهش Coupling و اهمیت عوامل انسانی در طراحی سیستمها تأکید داشتند.بنابراین، معماری خوب، معماریای است که در برابر تغییرات آینده انعطافپذیر باشد و بتواند همزمان نیازهای فنی، کسبوکار و تیم توسعه را بهخوبی متعادل کند.«اين مطلب، بخشي از تمرين درس معماري نرمافزار دانشگاه شهيد بهشتی است.»</description><category>Maedeh Zarei</category><author>Maedeh Zarei</author><pubDate>Sun, 12 Jul 2026 01:13:59 +0330</pubDate></item><item><title>مفاهیم کلیدی و ترند در معماری نرم‌افزار؛ اصطلاحاتی که هر مهندس نرم‌افزار باید بداند!</title><link>https://virgool.ir/@MaedehZarei/مفاهیم-کلیدی-و-ترند-در-معماری-نرم-افزار-اصطلاحاتی-که-هر-مهندس-نرم-افزار-باید-بداند-qjouwmoc3ezg</link><description>با رشد سریع دنیای مهندسی نرم‌افزار، هر روزه با اصطلاحات و مفاهیم جدیدی مواجه می‌شیم.در این پست، قراره به طور خلاصه، به 20 مورد از مهم‌ترین، مدرن‌ترین و البته پرکاربردترین مفاهیم این حوزه بپردازیم؛ مفاهیمی که از معماری‌های توزیع‌شده تا تقاطع جذاب هوش مصنوعی و مهندسی نرم‌افزار رو در بر می‌گیرن.این لیست یک «نقشه راه» جامع برای برنامه‌نویسان، معماران و مهندسان نرم‌افزار و دانشجوهاست!در پست‌های آینده هم، عمیق‌تر شده و تک‌تک این موضوعات رو با جزئیات فنی‌تر، چالش‌های پیاده‌سازی و نمونه‌های واقعی بررسی خواهیم کرد.Chaos Engineeringمفهوم مهندسی آشوب/Chaos Engineering، به منظور اینه که به جای منتظر موندن برای وقوع یک خطای واقعی در سیستم، خودمون اون خطا رو به صورت کنترل شده به سیستم اعمال کنیم تا میزان مقاومتش رو سنجیده و افزایش بدیم. با این کار می‌تونیم تاب آوری/tolerance سیستممون رو در زمان اجرا (runtime) و در محیط production ارتقا داده و قابلیت دسترس پذیری/availability رو در سطوح بالا محقق کنیم.این رویکرد پیشگیرانه ریشه در تجربه‌ای از خرابی سه روزه در سال 2008 در نتفلیکس/Netflix داره که برای مقابله با اون، در سال 2010، ابزاری به نام Chaos Monkey توسط نتفلیکس توسعه یافت تا بتونه چالش‌های مربوط به انعطاف‌پذیری/flexibility سیستم‌های توزیع شده و مقیاس‌وسیع در بستر ابر رو برطرف کنه.Chaos EngineeringBackend for Frontendالگوی معماری Backend for Frontend، یک الگوی طراحی توزیع شده برای پاسخگویی به نیازهای ناشی از گستردگی و تنوع دستگاه‌های کلاینت در سیستم‌های میکروسرویسه که به جای استفاده از یک API واحد و عمومی برای تمام کلاینت‌ها، یک backend اختصاصی و جداگانه رو برای هر UI منحصر به فرد توسعه می‌ده.این الگوی معماری گلوگاه‌های سازمانی رو از بین برده و به تیم‌های frontend استقلال بالایی در به‌روزرسانی رابط‌های کاربری اعطا می‌کنه که باعث میشه با تغییر در هر frontend، سایر frontها تحت تاثیر قرار نگیرن.برای مثال، SoundCloud با پیاده‌سازی این الگو تونست APIهای خودش رو برای هر نوع کلاینت جداگانه بهینه کند، و بدون نیاز به هماهنگی‌های پیچیده، قابلیت تحمل خطا/resiliency و سرعت توسعه رو بهبود ببخشه.Backend for FrontendArtificial Intelligence for Software Engineering (AI4SE)اصطلاح AI4SE، به معنای هوش‌ مصنوعی در خدمت مهندسی نرم‌افزاره که به کاربرد الگوریتم‌ها و توانمندی‌های هوش مصنوعی برای بهبود فرایندهای توسعه نگهداری و تست نرم‌افزار اشاره کرده و در راستای خودکارسازی ارتقا و بهینه‌سازی فرایندهای گوناگون چرخه حیات توسعه نرم‌افزار به کمک هوش‌ مصنوعیه.ابزارهایی مثل GitHub Copilot، Cursor AI و Amazon CodeWhisperer نمونه‌های بارز AI4SE هستن که می‌تونن کد رو به صورت خودکار تولید کنن، تست‌های نرم‌افزاری به ویژه unit testها رو بنویسن، باگ‌ها را شناسایی و حتی رفع کرده و مستندات فنی رو استخراج کنن.Software Engineering for Artificial Intelligence (SE4AI)در نقطه مقابل، SE4AI به معنای مهندسی نرم‌افزار در خدمت هوش مصنوعیه و روی توسعه سیستم‌های مبتنی بر هوش مصنوعی با استانداردها و متدولوژی‌های مهندسی نرم‌افزار رای ساخت استقرار نظارت و مدیریت این سیستم‌ها تمرکز دارد تا reliability، security و scalability رو محقق کنه.یکی از چالش‌های اصلی SE4AI، استقرار و عملیاتی کردن مدل‌های هوش مصنوعی در محیط واقعیه. تحقیقات نشون می‌ده که توسعه یک مدل AI فقط ۲۰ تا ۳۰ درصد کار رو تشکیل می‌دهه و مابقی زمان، صرف یکپارچه‌سازی، تست، نظارت و نگهداری آن می‌شه. اینجاست که مفاهیمی مثل MLOps (که در بخش بعد به اون می‌پردازیم) و تکنیک‌های مهندسی نرم‌افزار وارد عمل می‌شن.در واقع SE4AI به ما یاد می‌ده که باید مدل‌های AI رو همانند کدهای نرم‌افزاری، تحت کنترل نسخه قرار دهیم، خطوط لوله استقرار خودکار برای اون‌ها تعریف کنیم و عملکردشون رو در محیط تولید به طور مداوم پایش کنیم.AI4SE &amp; SE4AIMachine Learning Operations (MLOps)این اصطلاح که برگرفته و با الهام از DevOps هست و به مجموعه شیوه‌ها، ابزارها و فرهنگ توسعه گفته می‌شه که چرخه حیات کامل سیستم‌های یادگیری ماشین رو خودکارسازی، یکپارچه‌سازی و مدیریت می‌کنه، از جمع‌آوری داده و آموزش مدل تا استقرار، نظارت و بازآموزی (relearn) مداوم ا‌ون.تفاوت اصلی MLOps با DevOps در ماهیت پروژه‌هاست. در DevOps، ما با کد و نرم‌افزارهای قطعی/deterministic سر و کار داریم که اگر یک بار درست کار کنه، همیشه درست کار خواهد کرد؛ ولی در MLOps، سیستم‌ها، غیرقطعی/nondeterministic و وابسته به داده هستن. مدل‌ها می‌تونن با تغییر داده یا تغییر روابط به مرور زمان خراب بشم، بدون اینکه حتی یک خط از کدشون تغییر کرده باشد. MLOps برای حل این چالش‌ها راهکارهای مشخصی ارائه می‌ده.پلتفرم‌های تراز اول MLOps نظیر Amazon SageMaker خطوط لوله جامعی رو برای مدیریت این فرآیندها ارائه می‌دن که ثبات/stability و قابلیت اطمینان/reliability سیستم‌های هوشمند رو در مقیاس سازمانی تضمین می‌کنن.Machine Learning Operations (MLOps)Infrastructure as Codeمفهوم Infrastructure as Code یا زیرساخت به عنوان کد، به این معناست که به جای تنظیم دستی و کلیک کردن در پنل‌های ابری برای ساخت سرور یا شبکه‌ها، کل زیرساختمون رو با کدهای متنی و خوانا برای ماشین (مثل YAML یا HCL) توصیف کنیم. این کار باعث می‌شه خطاهای انسانی به حداقل برسه و محیط‌های توسعه، تست و production کاملاً شبیه به هم باشن.این رویکرد دو مدل اصلی داره: یا به صورت اعلامی/declarative (مثل ابزارهای Terraform و CloudFormation) فقط به سیستم می‌گیم چه وضعیت نهایی رو می‌خوایم، یا به صورت دستوری/imperative (مثل AWS CDK) با زبان‌های برنامه‌نویسی رایج مثل پایتون زیرساخت رو می‌نویسیم. از اونجایی که این فایل‌ها مثل کدهای نرم‌افزاری وارد مخازن مانیتورنگ و کنترل نسخه (Git) می‌شن، می‌تونیم براشون تاریخچه تغییرات، requests و تست‌های خودکار داشته باشیم و استقرار رو کاملاً خودکار (CI/CD) پیش ببریم.Infrastructure as CodeAPI Gateway &amp; Service Meshتوی معماری میکروسرویس، برای مدیریت ارتباطات از دو الگوی API Gateway و Service Mesh استفاده می‌شه که هر کدوم لایه‌ها و اهداف متفاوتی دارن. الگوی API Gateway مثل یک درگاه ورودی واحد برای کلاینت‌های خارجی عمل می‌کنه و ترافیک شمال-جنوب/North-South رو مدیریت می‌کنه؛ یعنی کارهایی مثل احراز هویت، محدودیت نرخ درخواست/rate limiting، کش کردن و مسیریابی رو قبل از رسیدن درخواست به داخل سیستم متمرکز می‌کنه.از طرف دیگه، Service Mesh روی ترافیک شرق-غرب/East-West یعنی ارتباطات بین خود میکروسرویس‌ها در داخل سیستم تمرکز داره. این الگو با قرار دادن یک پراکسی سبک (معروف به Sidecar مثل Envoy) کنار هر سرویس، بدون نیاز به تغییر در کدهای اصلی برنامه، امکاناتی مثل امنیت (رمزنگاری mTLS)، پایداری (circuit breaker) و مانیتورینگ رو برای ارتباطات داخلی cluster تضمین می‌کنه.API Gateway &amp; Service MeshCommand Query Responsibility Segregation (CQRS)در بسیاری از سیستم‌های سنتی، خوندن و نوشتن داده‌ها هر دو از یک مدل داده و یک پایگاه داده استفاده می‌کنن. این روش تا جایی که میزان خوندن و نوشتن متوازنه و پیچیدگی کمی داره، به خوبی کار می‌کنه، ولی زمانی که یک عملیات در سیستم نیاز به بهینه‌سازی‌های کاملاً متفاوتی داشته باشه، مثلا تو سیستم‌های پیچیده که نرخ خوندن و نوشتن خیلی متفاوته (همچون شبکه‌های اجتماعی)، این روش باعث افت کارایی و پیچیدگی می‌شه. با CQRS، ما سیستم رو به دو بخش مجزا تقسیم می‌کنیم که حتی می‌تونن دیتابیس‌های فیزیکی جداگانه‌ای داشته باشن؛ یکی برای نوشتن که منطق پیچیده کسب‌وکار رو هندل می‌کنه و یکی برای خوندن که برای سرعت بالا و جستجو بهینه‌سازی شده. این دو بخش معمولاً از طریق رویدادها/events به صورت ناهمگام با هم در ارتباطن (که باعث پایداری نهایی/Eventual Consistency می‌شه)، ولی به خاطر پیچیدگی بالایی که داره، برای پروژه‌های ساده و معمولی به هیچ وجه توصیه نمی‌شه.Command Query Responsibility Segregation (CQRS)Event-Driven Architecture (EDA)در معماری‌های سنتی مبتنی بر درخواست/request-driven، یک کامپوننت، معمولا به صورت همگام و به طور مستقیم کامپوننت دیگه رو صدا می‌زنه و منتظر پاسخ می‌مونه؛ ولی در معماری رویداد-محور (EDA)، این رابطه وارونه می‌شوه: به جای اینکه یک سرویس، سرویس دیگه رو صدا بزنه، رویدادها/events رو منتشر می‌کنه که بیانگر اتفاقیه که قبلاً رخ داده یا کاریه که انجام داده. بنابراین، سایر سرویس‌ها بدون اینکه بدونن چه کسی رویداد را منتشر کرده، به اون گوش می‌دن و در صورت لزوم واکنش نشان می‌دن.این رویکرد وابستگی و coupling بین سرویس‌ها رو از بین می‌بره و به خاطر استفاده از یک واسط پیام (Message Broker)، مقیاس‌پذیری افقی/horizontal scalability و resiliency فوق‌العاده‌ای به سیستم می‌ده. یعنی حتی اگر سرویس دریافت‌کننده در دسترس نباشه، پیام تو صف می‌مونه تا بعداً پردازش بشه؛ هرچند دیباگ کردن این سیستم‌های توزیع‌شده و مدیریت ترتیب رویدادها چالش‌های خاص خودش رو داره.این معماری مبنای بسیاری از سیستم‌های بزرگ مانند Netflix، Uber و سیستم‌های تریدینگه.Event-Driven Architecture (EDA)Serverless Architectureدر معماری سنتی، شما باید سرور (مجازی یا فیزیکی) رو تهیه، پیکربندی و مدیریت کنید. در Serverless Architecture، شما فقط کدتون رو می‌نویسید و پلتفرم ابری (مثل AWS Lambda، Azure Functions یا Google Cloud Functions)، مسئولیت اجرا، scaling و مدیریت زیرساخت رو بر عهده می‌گیره و مدل پرداخت به صورت micro-billing هست؛ یعنی فقط به اندازه همون چند میلی‌ثانیه‌ای که کدمون اجرا شده پول می‌دیم و نیازی به سرورهای همیشه روشن نیست.پس معماری بدون سرور به این معنی نیست که واقعاً سروری وجود نداره، بلکه یعنی مدیریت سخت‌افزار، مقیاس‌پذیری و نگهداری زیرساخت کاملاً به عهده شرکت ارائه‌دهنده ابریه و ما به عنوان توسعه‌دهنده فقط روی نوشتن منطق تجاری کدمون تمرکز می‌کنیم. این معماری معمولاً با مدل Function-as-a-Service (FaaS) مثل AWS Lambda پیاده می‌شه که کدمون فقط در پاسخ به یک رویداد خاص (مثل درخواست HTTP) اجرا می‌شه.با این حال، محدودیت‌هایی مثل زمان اجرای کوتاه و مشکل cold start (تاخیر در اولین اجرای کد بعد از یک مدت بیکاری) از چالش‌های اصلی این الگو به حساب میان.Serverless ArchitectureAPI-first Approachرویکرد API-first به این تاکید داره که قبل از اینکه حتی یک خط کد بک‌اند بنویسیم، اول در مورد شکل و مشخصات API با تمام تیم‌ها به توافق می‌رسیم، اون رو مستند کرده و در specification قرار می‌دیم و با استانداردهایی مثل OpenAPI یا GraphQL Schema اون رو طراحی می‌کنیم.خوبی این روش اینه که تیم‌های frontend و backend می‌تونن با استفاده از داده‌های شبیه‌سازی‌شده (به کمک mock server) به صورت کاملاً موازی کارشون رو پیش ببرن. این کار هم هماهنگی بین تیم‌ها و سرعت عرضه محصول به بازار رو بالا می‌بره، هم جلوی ناهماهنگی‌های مخرب رو تو مراحل نهایی ادغام و یکپارچه‌سازی سیستم می‌گیره.API-first ApproachDomain-Driven Design (DDD)طراحی مبتنی بر دامنه (DDD) یا بهتر بگم دامنه‌رانه، یک متدولوژی برای مدل‌سازی سیستم‌های نرم‌افزاری پیچیده بر اساس قلمرو business domain و business logic است، نه بر اساس جزئیات فنی مانند DB یا framework. این روش، سیستم رو به بخش‌های مستقل و کوچکتری به نام bounded context تقسیم می‌کنه که هر کدوم مدل ذهنی و مفاهیم خاص خودشون رو دارن.مهم‌ترین اصل DDD در سطح استراتژیک، استفاده از یک زبان یکسان/Ubiquitous Language بین تیم فنی و کارشناسان کسب‌وکاره تا هیچ ابهامی تو ارتباطات و کدنویسی پیش نیاد. تو سطح تاکتیکی هم با مفاهیمی مثل موجودیت‌ها، value objects و aggregates، منطق کسب‌وکار رو طوری پیاده می‌کنه که از تبدیل شدن سیستم به یک ساختار درهم‌تنیده و مخرب (Big Ball of Mud) جلوگیری بشه.پیاده‌سازی DDD معمولاً منجر به یک معماری لایه‌ای تمیز/clean architecture می‌شه که در اون domain layer کاملاً از لایه‌های زیرساخت (DB، UI، و...) جدا هست. این جداسازی باعث می‌شود منطق کسب‌وکار «قلب» نرم‌افزار باقی بمونه و تحت تأثیر تغییرات فنی قرار نگیره.Domain-Driven Design (DDD)Hexagonal Architectureمعماری شش‌ضلعی که بهش الگوی Ports and Adapters هم می‌گن، دقیقاً برای این ابداع شده که هسته مرکزی و منطق کسب‌وکار سیستم رو از تکنولوژی‌های بیرونی (مثل DBs و web framewors) کاملاً ایزوله کنه.تو این الگو که پایه معماری تمیز هم هست، ارتباط سیستم با دنیای بیرون فقط از طریق واسط‌های انتزاعی به نام درگاه/port و پیاده‌سازی‌های ملموس اون‌ها یعنی آداپتور/adapter انجام می‌شه. این ساختار باعث می‌شه که بتونیم کل منطق هسته رو بدون نیاز به شبکه یا دیتابیس واقعی تست کنیم و اگر روزی خواستیم framework یا DB رو عوض کنیم، این کار رو بدون تغییر دادن حتی یک خط از کدهای هسته انجام بدیم.پس معماری شش‌ضلعی، برای پروژه‌های بلندمدتی که نیاز به انعطاف‌پذیری/flexibility، قابلیت نگهداری/maintainability و قابلیت تست/testability بالا دارن، ایده‌آله.پ.ن: مفهوم Ports and Adapters، از اون مفاهیم و نکات کلیدی تو مهندسی نرم‌افزاره که همونطور که اینجا هم توضیح دادم، portها، واسط‌/interfaceهای زبان برنامه‌نویسی هستن که در لایه هسته تعریف می‌شن و مشخص می‌کنند که سیستم چه خدماتی باید ارائه بده؛ adapterها هم پیاده‌سازی این واسط‌ها در لایه زیرساخت هستن.Hexagonal ArchitectureDDD-hexagonal-onion-clean-CQRS, how to put it all togetherEvent Sourcingدر این الگو، به جای اینکه فقط وضعیت فعلی یک موجودیت رو ذخیره کنیم، تمام رویدادهای غیرقابل تغییری که باعث تغییر وضعیت شدن رو به ترتیب در یک لاگ افزایشی/append-only به نام event store ذخیره می‌کنیم.حالا، برای به دست آوردن آخرین وضعیت یک داده، سیستم باید رویدادهای گذشته رو از ابتدا بازپخش کرده و از روی اون‌ها وضعیت رو محاسبه ‌کنه.اگرچه این کار برای حجم داده‌های بالا نیازمند تکنیک‌هایی مثل ذخیره موقت/snapshot هست، اما مزایای بی‌نظیری مثل داشتن تاریخچه کامل تغییرات و قابلیت بازبینی/auditability، بازگردانی وضعیت سیستم به هر نقطه زمانی در گذشته و هماهنگی کاملاً طبیعی با الگوی CQRS رو بهمون می‌ده.پ.ن: اتفاقا Uncle Bob در کتاب Clean Architecture، مفهوم event sourcing را به عنوان یکی از کاربردهای functional programming معرفی می‌کنه و استدلال می‌کنه که اگر ما به جای ذخیره آخرین وضعیت داده‌ها، تمام رویدادها را به صورت تغییرناپذیر/Immutable ذخیره کنیم، نه تنها هیچ داده‌ای را از دست نمی‌دهیم، بلکه مشکلاتی مثل بن‌بست‌ها/deadlocks و تداخل‌های همزمانی/concurrency در سیستم‌های پیچیده به طور کلی حذف می‌شه.Event SourcingLow-code/No-code platformsپلتفرم‌های LC/NC سیستم‌هایی هستن که به توسعه‌دهنده‌ها و افراد غیرفنی اجازه می‌دن با استفاده از واسط‌های گرافیکی Drag-and-Drop، پیکربندی ساده و با کمترین نیاز به کدنویسی دستی، اپلیکیشن بسازن. ابزارهای No-code بیشتر برای افراد غیرفنی/citizen developers هدف‌گذاری شدن، در حالی که ابزارهای Low-code به برنامه‌نویس‌ها این امکان رو می‌دن که تو بخش‌های پیچیده‌تر، کدهای سفارشی خودشون رو هم تزریق کنن.با اینکه این پلتفرم‌ها زمان و هزینه تحویل پروژه رو به شدت کاهش می‌دن، اما چالش‌های بزرگی هم برای معماری سازمان دارن؛ مشکلاتی مثل قفل‌شدگی شدید به پلتفرم ارائه‌دهنده/vendor lock-in، رشد اپلیکیشن‌های خارج از نظارت امنیتی سازمان (Shadow IT) و ناتوانی در پشتیبانی از تراکنش‌های بسیار سنگین باعث می‌شه که جایگزین کاملی برای توسعه سیستم‌های اصلی و پیچیده نباشن.Low-code/No-code platformsBusiness Process Management Systems (BPMS)در بسیاری از سازمان‌های بزرگ، فرآیندهای اصلی کسب‌وکار از چندین مرحله تشکیل شده‌ که توسط افراد مختلف و گاهی با فاصله زمانی زیاد انجام می‌شه. سیستم‌های BPMS پلتفرم‌های نرم‌افزاری هستن که این فرآیندها را به صورت خودکار و یکپارچه، تو لایه‌های مختلف کسب‌وکار، مدیریت و هماهنگ می‌کنن. یک BPMS معمولاً از سه لایه اصلی تشکیل شده:1. موتور فرآیند/Process Engine2. صفحه‌کار/Worklist3. ابزارهای یکپارچه‌سازی/Integration Toolsاین سیستم‌ها معمولاً از استاندارد جهانی BPMN 2.0 استفاده می‌کنن تا فرآیندها رو به صورت گرافیکی رسم کنن و موتور پردازشگر/process engine مستقیماً همون مدل‌ها رو تفسیر و مسیریابی می‌کنه.تو معماری‌های مدرن و میکروسرویسی امروزی، BPMSها به عنوان هماهنگ‌کننده مرکزی و orchestrator به کار می‌رن. ابزارهای قدرتمندی مثل Camunda با بهره‌گیری از الگوی Saga، می‌تونن تراکنش‌های توزیع‌شده طولانی‌مدت رو مدیریت کنن و اگر خطایی تو طول مسیر رخ داد، با فراخوانی اقدامات جبرانی، پایداری داده‌ها رو تو کل سیستم حفظ کنن.Low-code/No-code platformsMessage Queueدر معماری‌های توزیع‌شده، اگر یک سرویس به طور مستقیم و همگام سرویس دیگه رو صدا بزنه و سرویس مقصد در دسترس نباشه یا کند باشه، کل سیستم دچار مشکل می‌شه. Message Queue به کمک یک واسط ناهمگام/asynchronous intermediary به جای ارتباط مستقیم، سرویس فرستنده پیام رو در یک صف قرار می‌ده و بدون اینکه منتظر پاسخ باشه، به کارش ادامه می‌ده؛ حالا، هر زمان که سرویس دریافت‌کننده آماده بود، پیام رو از صف برداشته و پردازش می‌کنه.تو این فضا دو ابزار قدرتمند با الگوهای متفاوت داریم: RabbitMQ و Apache Kafka.ابزار RabbitMQ یک کارگزار پیام کلاسیکه/push-based که پیام رو به دست مصرف‌کننده می‌رسونه و بلافاصله بعد از تایید دریافت، اون رو پاک می‌کنه؛ بنابراین برای ارتباطات بین‌سرویسی سنتی و مسیریابی‌های دقیق عالیه. ولی Kafka یک پلتفرم استریم توزیع‌شده است که پیام‌ها رو مثل یک لاگ دائمی روی دیسک ذخیره می‌کنه/pull-based تا مصرف‌کننده‌ها با سرعت خودشون پیام‌ها رو بخونن یا حتی بازپخش کنن. این ویژگی، kafka رو برای پردازش جریان‌های داده‌ای خیلی حجیم و معماری‌های رویدادمحور بی‌رقیب می‌کنه.Message QueueContainers and Container Orchestrationفناوری کانتینرسازی (مثل ابزار Docker) به وجود اومد تا کدهای یک برنامه رو با تمام کتابخونه‌ها و وابستگی‌هاش تو یک واحد مجزا و ایزوله بسته‌بندی کنه. کانتینرها برخلاف ماشین‌های مجازی (VM)، هسته سیستم‌عامل میزبان رو به اشتراک می‌ذارن و به همین دلیل بسیار سبک‌ترن و تو کسری از ثانیه اجرا می‌شن. ولی زمانی که سیستم بزرگ می‌شه و با ده‌ها یا صدها کانتینر مواجه می‌شیم، مدیریت دستی اون‌ها عملاً غیرممکنه. اینجاست که پلتفرم‌های orchestration مثل Kubernetes وارد عمل می‌شن. کوبر وظیفه داره که containerها رو auto-scale کرده و بار ترافیکی رو توزیع کنه و اگر یک کانتینر از کار افتاد، بلافاصله اون رو جایگزین کنه (Self-Healing).Containers and Container OrchestrationMulti-Tenancy Architectureاین معماری، مبنای سرویس‌های ابری و SaaS هست؛ به این شکل که با راه‌اندازی فقط یک نسخه واحد از نرم‌افزار، به ده‌ها یا صدها شرکت و سازمان مختلف (مستأجر/tenant) سرویس داده می‌شه، در حالی که داده‌های هر سازمان کاملاً از بقیه جدا و ایزوله است.برای این جداسازی سه رویکرد وجود داره: داشتن دیتابیس مجزا برای هر مشتری (گران اما بسیار امن)، استفاده از Schema جداگانه در یک دیتابیس مشترک، و یا قرار دادن همه داده‌ها تو یک جدول و تفکیک کردنشون با یک فیلد شناسایی مثل tenant_id (کم‌هزینه‌ترین اما نیازمند مدیریت دقیق).این معماری هزینه‌های عملیاتی رو به شدت کاهش می‌ده و به‌روزرسانی سیستم رو خیلی یکپارچه و راحت می‌کنه، اما اصلی‌ترین چالش اون جلوگیری از نشت اطلاعات بین tenantهاست.Multi-Tenancy ArchitectureData Migrationمهاجرت داده یکی از پرریسک‌ترین کارهای مهندسی نرم‌افزاره و زمانی انجام می‌شه که بخوایم دیتابیس قدیمی رو تغییر بدیم یا داده‌ها رو برای شکستن یک معماری یکپارچه به میکروسرویس‌ها تفکیک کنیم.از اونجا که داده قلب تپنده سیستمه، هر خطایی تو این مسیر می‌تونه فاجعه‌بار باشه.برای این کار معمولاً از سه استراتژی استفاده می‌شه: رویکرد Big Bang (خاموش کردن سیستم قدیمی و انتقال یکباره داده‌ها که باعث دان‌تایم می‌شه)، رویکرد تدریجی/Trickle (کار کردن موازی سیستم قدیم و جدید مثل الگوی Strangler Fig)، و جذاب‌ترین مدل یعنی Zero-Downtime که تو اون بدون توقف سیستم، داده‌ها به صورت بلادرنگ همگام می‌شن.موفقیت تو این فرآیند که مبتنی بر ابزارهای ETL (Extract, Transform, Load) هست، نیازمند پایش مداوم و نوشتن برنامه‌های دقیق برای بازگشت‌پذیری و rollback کردن در زمان خطاست.Data Migrationسخن پایانیسعی کردم تو این پست، یک نمای کلی و سریع از 20 مفهوم و ترند مهمی که دنیای امروز مهندسی نرم‌افزار رو شکل می‌دن، ارائه بدم. همون‌طور که دیدید، از زیرساخت و کانتینرها گرفته تا الگوهای پیچیده‌تری مثل CQRS و Event Sourcing، همه این‌ها مثل قطعات یک پازل بزرگ هستن که به ما کمک می‌کنن سیستم‌های پایدارتر، مقیاس‌پذیرتر و تمیزتری بسازیم.خوندن این مفاهیم پشت سر هم ممکنه کمی سنگین باشه، اما فراموش نکنید که این مقاله فقط یک roadmap بود تا چشم‌انداز کلی رو ببینیم و در پست‌های آینده قراره تمام این الگوها رو زیر ذره‌بین ببریم، چالش‌های پیاده‌سازی‌شون رو تو دنیای واقعی بررسی کنیم و ببینیم چطور می‌شه ازشون تو معماری پروژه‌های خودمون استفاده کرد.مرسی که تا اینجا همراه من بودید.تا پست‌های بعدی، خدانگهدارتون!</description><category>Maedeh Zarei</category><author>Maedeh Zarei</author><pubDate>Tue, 02 Jun 2026 06:11:35 +0330</pubDate></item></channel></rss>