概要
Chain of Responsibility(責任の連鎖)パターンは、
複数の処理者(ハンドラー)をチェーン状に接続し、順に処理を委譲していく構造的デザインパターンである。
処理の流れを分岐やif文に依存せず、構造で制御できるようになるのが特徴。
リクエスト処理、バリデーション、ミドルウェア的な実装に適している。
1. なぜChain of Responsibilityが必要か?
❌ 複数の条件分岐による責務処理
if request.type == "auth":
handle_auth(request)
elif request.type == "log":
handle_log(request)
elif request.type == "notify":
handle_notify(request)
→ 条件が増えるほどコードが分岐し、メンテナンスが困難に
✅ 各責務をチェーンでつなぎ、順に処理させる
auth.set_next(log).set_next(notify)
auth.handle(request)
→ 処理フローをコードでなくオブジェクト構造で制御
2. 基本構造
✅ Handler基底クラス
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(処理の実体)
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)
✅ 使用例
request = {"auth": True}
auth = AuthHandler()
log = LogHandler()
notify = NotifyHandler()
auth.set_next(log).set_next(notify)
auth.handle(request)
出力:
AuthHandler: 認証済み
LogHandler: ログ記録
NotifyHandler: 通知送信
3. 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
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パターンはその流れと責任を、静かに繋ぎ、整えるための技法である。