結合度
モジュール間の依存の強さを示す設計指標で、低いほど保守性が高い
設計設計原則
結合度とは
結合度 (Coupling) は、モジュール間の依存の強さを示す設計指標で、低いほど保守性が高い。凝集度 (Cohesion) と対になる概念で、「高凝集・低結合」が良い設計の基本。
結合度のレベル
| レベル | 説明 | 品質 |
|---|---|---|
| メッセージ結合 | メソッド呼び出しのみ | ✅ 最低 (最良) |
| データ結合 | プリミティブなデータを渡す | ✅ 低い |
| スタンプ結合 | オブジェクトを渡す (一部しか使わない) | △ 中 |
| 制御結合 | フラグで相手の動作を制御 | ❌ 高い |
| 内容結合 | 相手の内部実装に依存 | ❌ 最高 (最悪) |
高結合の例
// ❌ 内容結合: OrderService が UserService の内部実装に依存
class OrderService {
createOrder(userId: string) {
const user = userService.users.find(u => u.id === userId); // 内部の配列に直接アクセス
if (user.creditScore > 700) { ... } // 内部のフィールドに依存
}
}
低結合の例
// ✅ メッセージ結合: インターフェース経由でアクセス
interface UserService {
canPlaceOrder(userId: string): Promise<boolean>;
}
class OrderService {
constructor(private userService: UserService) {}
async createOrder(userId: string) {
if (await this.userService.canPlaceOrder(userId)) { ... }
}
}
AWS での疎結合パターン
| パターン | 結合度 | 説明 |
|---|---|---|
| 直接呼び出し (Lambda → Lambda) | 高い | 呼び出し元が呼び出し先を知っている |
| キュー (SQS) | 低い | プロデューサーとコンシューマーが独立 |
| イベント (EventBridge) | 最低 | プロデューサーはコンシューマーを知らない |
# ❌ 高結合: Lambda A が Lambda B を直接呼び出し
# ✅ 低結合: SQS を介して疎結合に
OrderFunction:
Properties:
Environment:
Variables:
NOTIFICATION_QUEUE: !Ref NotificationQueue
# OrderFunction は NotificationFunction の存在を知らない
結合度を下げる手法
具体的な実装ではなく抽象 (インターフェース) に依存し、直接呼び出しではなくイベントで連携するイベント駆動を採用する。SQS のようなメッセージキューで非同期に疎結合にし、接続先は環境変数で管理してハードコードしない。
時間的結合
❌ 時間的結合: A の後に B を実行する必要がある
await processOrder();
await sendNotification(); // processOrder が終わらないと実行できない
✅ 非同期で解消:
await processOrder();
await sqs.send({ ... }); // 通知は非同期で処理
結合度の関連書籍も参考になる。