Pythonで実装するChain of Responsibilityパターン：責務の連鎖で柔軟な処理フローを構築する



## 概要

**Chain of Responsibility（責任の連鎖）パターン**は、  
複数の処理者（ハンドラー）をチェーン状に接続し、**順に処理を委譲していく構造的デザインパターン**である。

処理の流れを**分岐やif文に依存せず、構造で制御できるようになる**のが特徴。  
リクエスト処理、バリデーション、ミドルウェア的な実装に適している。

---

## 1. なぜChain of Responsibilityが必要か？

### ❌ 複数の条件分岐による責務処理

```python
if request.type == "auth":
    handle_auth(request)
elif request.type == "log":
    handle_log(request)
elif request.type == "notify":
    handle_notify(request)
```

→ 条件が増えるほど**コードが分岐し、メンテナンスが困難に**

---

### ✅ 各責務をチェーンでつなぎ、順に処理させる

```python
auth.set_next(log).set_next(notify)
auth.handle(request)
```

→ **処理フローをコードでなくオブジェクト構造で制御**

---

## 2. 基本構造

### ✅ Handler基底クラス

```python
class Handler:
    def __init__(self):
        self._next = None

    def set_next(self, handler):
        self._next = handler
        return handler

    def handle(self, request):
        if self._next:
            return self._next.handle(request)
```

---

### ✅ Concrete Handlers（処理の実体）

```python
class AuthHandler(Handler):
    def handle(self, request):
        if request.get("auth"):
            print("AuthHandler: 認証済み")
        else:
            print("AuthHandler: 未認証。処理停止")
            return
        super().handle(request)

class LogHandler(Handler):
    def handle(self, request):
        print("LogHandler: ログ記録")
        super().handle(request)

class NotifyHandler(Handler):
    def handle(self, request):
        print("NotifyHandler: 通知送信")
        super().handle(request)
```

---

### ✅ 使用例

```python
request = {"auth": True}

auth = AuthHandler()
log = LogHandler()
notify = NotifyHandler()

auth.set_next(log).set_next(notify)

auth.handle(request)
```

出力:
```
AuthHandler: 認証済み
LogHandler: ログ記録
NotifyHandler: 通知送信
```

---

## 3. Python的応用：関数ベースのチェーン構築

```python
def auth_middleware(req, next_handler):
    if req.get("auth"):
        print("[auth] pass")
        return next_handler(req)
    print("[auth] reject")

def log_middleware(req, next_handler):
    print("[log] recorded")
    return next_handler(req)

def notify_middleware(req, next_handler):
    print("[notify] sent")
    return next_handler(req)

def build_chain(*middlewares):
    def call(req):
        def _call(index):
            if index >= len(middlewares):
                return
            return middlewares[index](req, lambda r: _call(index + 1))
        return _call(0)
    return call
```

```python
chain = build_chain(auth_middleware, log_middleware, notify_middleware)
chain({"auth": True})
```

→ **ミドルウェアスタイルの非同期・非ブロッキング処理に応用可能**

---

## 4. 実務ユースケース

### ✅ Webフレームワークのミドルウェアチェーン

→ 認証、バリデーション、ログ、変換処理など**段階的に通す**

---

### ✅ バリデーションロジックの組み合わせ

→ 入力値に対する**検証ロジックを順に適用してエラー検出**

---

### ✅ エラーハンドリングの委譲処理

→ **例外の発生場所によって異なる責任者に処理を委譲**

---

### ✅ チェックポイント式のビジネスフロー構築

→ 顧客データ、与信、在庫、承認などを**順に確認するプロセス設計**

---

## 5. よくある誤用と対策

### ❌ チェーン内で次の処理を忘れて中断

→ ✅ **常に `super().handle(request)` を呼ぶ or 明示的に next() を設計に含める**

---

### ❌ 全てのハンドラーが必ず呼ばれてしまう

→ ✅ **処理継続の条件分岐を設計内に明示的に持たせる**

---

### ❌ チェーンが長くなりすぎて可視性低下

→ ✅ **ハンドラ構成を外部で定義し、ログや可視化支援を取り入れる**

---

## 結語

**Chain of Responsibilityパターンとは、“責任を持った処理を順に流し、全体をしなやかに制御する構造”である。**

- if文を排除し、**オブジェクト指向的に処理を分割・接続**  
- 構造化された処理の流れにより、**再利用・構成変更・テストが容易に**  
- Pythonでは、クラスベース・関数ベースの両面から**柔軟にチェーン設計が可能**

**Pythonicとは、“条件ではなく構造で制御する”。  
Chain of Responsibilityパターンはその流れと責任を、静かに繋ぎ、整えるための技法である。**