凝集度
モジュール内の要素がどれだけ密接に関連しているかを示す設計指標
設計設計原則
凝集度とは
凝集度 (Cohesion) は、モジュール内の要素がどれだけ密接に関連しているかを示す設計指標である。凝集度が高いほど、モジュールの責務が明確で保守しやすい。結合度 (Coupling) と対になる概念。
凝集度のレベル
| レベル | 説明 | 品質 |
|---|---|---|
| 機能的凝集 | 1 つの機能を実現 | ✅ 最高 |
| 逐次的凝集 | 出力が次の入力になる | ✅ 高い |
| 通信的凝集 | 同じデータを操作 | △ 中 |
| 論理的凝集 | 論理的に似た処理をまとめる | ❌ 低い |
| 偶発的凝集 | 関連のない処理をまとめる | ❌ 最低 |
低い凝集度の例
// ❌ 偶発的凝集: 関連のない処理が 1 つのクラスに
class Utils {
formatDate(date: Date): string { ... }
calculateTax(amount: number): number { ... }
sendEmail(to: string, body: string): void { ... }
resizeImage(path: string, width: number): void { ... }
}
高い凝集度の例
// ✅ 機能的凝集: 注文に関する処理だけ
class OrderService {
async create(input: CreateOrderInput): Promise<Order> { ... }
async cancel(orderId: string): Promise<void> { ... }
async getById(orderId: string): Promise<Order | null> { ... }
}
// ✅ 機能的凝集: 通知に関する処理だけ
class NotificationService {
async sendOrderConfirmation(order: Order): Promise<void> { ... }
async sendShippingNotification(order: Order): Promise<void> { ... }
}
凝集度 vs 結合度
| 指標 | 目標 | 説明 |
|---|---|---|
| 凝集度 | 高い | モジュール内の関連性が高い |
| 結合度 | 低い | モジュール間の依存が少ない |
✅ 高凝集・低結合:
OrderService (注文の全責務) → NotificationService (通知の全責務)
→ 各モジュールが独立して変更可能
❌ 低凝集・高結合:
Utils (雑多な処理) ← 全モジュールが依存
→ Utils の変更が全体に波及
Lambda での凝集度
# ✅ 高凝集: 1 Lambda = 1 責務
CreateOrderFunction:
Events:
Api:
Path: /orders
Method: POST
GetOrderFunction:
Events:
Api:
Path: /orders/{id}
Method: GET
# ❌ 低凝集: 1 Lambda に全エンドポイント
MonolithFunction:
Events:
Api:
Path: /{proxy+}
Method: ANY
凝集度を高める指針
単一責任原則に従い、1 モジュールが変更される理由を 1 つに絞る。技術レイヤー (controller, service, repository) ではなくドメイン (注文、決済、配送) で分割する。雑多な関数の寄せ集めになりがちな Utils クラスは避け、関連するファイルを近くに配置 (コロケーション) する。
実践的な知識は関連書籍でも得られる。