🏗 راز معماری نابودنشدنی با Coupling و Cohesion
اگر بخواهیم فقط با دو مفهوم بفهمیم یک طراحی نرمافزاری چقدر سالم است، یکی از بهترین نقاط شروع این دو مفهوماند:
🔗 Coupling
🧩 Cohesion
خیلی وقتها این دو را کنار هم میشنویم، اما دقیقاً نمیدانیم چه مشکلی را حل میکنند.
بیایید از یک سؤال ساده شروع کنیم:
اگر فردا بخواهیم یک قسمت از سیستم را تغییر بدهیم، چند قسمت دیگر مجبور میشوند همراه آن تغییر کنند؟
پاسخ این سؤال، ما را مستقیماً به سمت Coupling میبرد.
🔗 ءCoupling چیست؟
ءCoupling یعنی میزان وابستگی بین Components مختلف سیستم.
هرچه دو Component برای کار کردن بیشتر به جزئیات یکدیگر وابسته باشند، Coupling آنها بیشتر است.
مثلاً:
{
اینجا
private readonly PaymentService _payment;
private readonly InventoryService _inventory;
private readonly EmailService _email;
public async Task CreateOrder()
{
await _payment.Pay();
await _inventory.Reserve();
await _email.Send();
}
}
OrderService مستقیماً به سه Component دیگر وابسته است.حالا فرض کنید API مربوط به
PaymentService تغییر کند.احتمالاً باید
OrderService را هم تغییر بدهیم.این یعنی یک تغییر محلی، اثر خود را به بیرون منتقل کرده است.
این همان چیزی است که در معماری میخواهیم تا حد امکان کنترلش کنیم.
🧩 ءCohesion چیست؟
ءCohesion تقریباً سؤال برعکس را میپرسد:
چیزهایی که داخل یک Component قرار دادهایم، واقعاً چقدر به یکدیگر مربوط هستند؟
اگر یک کلاس، Module یا Service روی یک هدف مشخص متمرکز باشد، Cohesion بالاتری دارد.
مثلاً:
├── AddItem()
├── RemoveItem()
├── CalculateTotal()
└── ApplyDiscount()
تمام این رفتارها حول یک مفهوم مشترک قرار گرفتهاند:🎯 Order
این یعنی Cohesion مناسب.
اما اگر همان کلاس تبدیل شود به:
├── CreateOrder()
├── SendEmail()
├── ResizeImage()
├── GenerateReport()
├── CreateUser()
├── ProcessPayment()
└── ClearCache()
دیگر یک مسئولیت مشخص نداریم.
کلاس به یک محل تجمع Business Logicهای نامرتبط تبدیل شده است.
اینجا Cohesion پایین آمده است.
🎯 پس هدف معماری چیست؟
یک قاعده بسیار مهم:
High Cohesion + Low Coupling
یعنی:
🧩 داخل هر Component، چیزهایی که واقعاً به هم مربوطاند کنار هم باشند.
و:
🔗 بین Componentها، وابستگی غیرضروری حداقل باشد.
این ترکیب یکی از اصول مهم در طراحی سیستمهای قابل نگهداری و قابل تغییر است. AWS نیز در راهنمای معماری خود برای Microservices صراحتاً بر Loose Coupling و High Functional Cohesion تأکید میکند.
💣 اما یک نکته مهم وجود دارد... Low Coupling به معنی:
«هیچ وابستگیای نباید وجود داشته باشد»
نیست.
این تصور اشتباه است.
یک سیستم بدون وابستگی عملاً وجود ندارد.
مثلاً:
↓
Payment
ءOrderبرای انجام یک فرآیند ممکن است واقعاً به Payment نیاز داشته باشد.
مسئله این نیست که Dependency را صفر کنیم.
مسئله این است که:
ءDependencyها را در مرزهای درست قرار دهیم.
🎯 یک معیار بسیار کاربردی
وقتی میخواهی تصمیم بگیری دو Component باید کنار هم باشند یا جدا، این سؤالها را بپرس:
🔹 آیا معمولاً با هم تغییر میکنند؟
🔹 آیا برای انجام یک Business Capability به یکدیگر نیاز دارند؟
🔹 آیا دادههایشان به شدت به هم وابسته است؟
🔹 آیا Transactionهای مشترک دارند؟
🔹 آیا یکی بدون دیگری میتواند مستقل Deploy شود؟
🔹 آیا یکی باید بتواند بدون دیگری کار کند؟
🔹 آیا تیمهای متفاوت مسئول آنها هستند؟
این سؤالها به ما کمک میکنند Boundary را بر اساس رفتار واقعی سیستم پیدا کنیم، نه بر اساس سلیقه.
