概要
Chain of Responsibility(責任の連鎖)パターンは、
リクエストを処理する複数のオブジェクトを、チェーン(鎖)のように接続し、
どこか一つが処理できれば他は無視され、処理できなければ次へ渡すという設計パターンである。
このパターンにより、責務の委譲・条件の分岐・処理の動的ルーティングをシンプルかつ拡張可能な形で表現できる。
1. なぜChain of Responsibilityが必要か?
❌ if-elif-else が膨張していく構造
def handle(request):
if request.type == "A":
return handle_a(request)
elif request.type == "B":
return handle_b(request)
else:
return default_handler(request)
→ 条件が増えるごとにコードが冗長化し、保守性が低下
✅ チェーンに処理責任を委譲する構造へ
handler = HandlerA(HandlerB(DefaultHandler()))
response = handler.handle(request)
→ 処理責任の分離とルーティングの柔軟化が可能に
2. 基本構造と実装
✅ 抽象ハンドラ
class Handler:
def __init__(self, next_handler=None):
self._next = next_handler
def handle(self, request):
if self._next:
return self._next.handle(request)
return None
✅ 具体的ハンドラ
class AuthHandler(Handler):
def handle(self, request):
if request.get("user"):
print("✅ Auth passed")
return super().handle(request)
print("❌ Auth failed")
return "Unauthorized"
class DataValidationHandler(Handler):
def handle(self, request):
if "data" in request:
print("✅ Data validated")
return super().handle(request)
print("❌ Invalid data")
return "Bad Request"
class FinalHandler(Handler):
def handle(self, request):
print("✅ Final processing complete")
return "Success"
✅ 実行例
pipeline = AuthHandler(DataValidationHandler(FinalHandler()))
req = {"user": "toto", "data": "payload"}
result = pipeline.handle(req)
print("Result:", result)
3. Python的に書きやすくする工夫
✅ デコレータスタイルのチェーン構築
def chain(handlers):
for i in range(len(handlers) - 1):
handlers[i]._next = handlers[i + 1]
return handlers[0]
pipeline = chain([
AuthHandler(),
DataValidationHandler(),
FinalHandler()
])
→ 構造の簡素化と柔軟な再構築が容易に
4. 実務ユースケース
✅ Webリクエストの前処理パイプライン
- 認証 → バリデーション → ロギング → 処理
✅ ログ出力:レベル別での責任転送
class InfoLogger(Handler):
def handle(self, msg):
if msg.level == "info":
print("[INFO]", msg.text)
else:
super().handle(msg)
✅ イベント処理:フィルタ・変換・通知のチェーン構築
- センサーデータの前処理など、動的フィルタリング構造に応用
5. よくある誤用と対策
❌ 全てのハンドラが処理してしまう
→ ✅ 一度処理されたら後続に渡さない設計(戻り値で分岐)を明確に定義する
❌ 無限ループのような循環参照を作る
→ ✅ ハンドラの終端条件を必ず設ける(デフォルトハンドラ or None)
❌ 適用範囲が広すぎてロジックが追えない
→ ✅ ハンドラごとに責務を限定し、チェーンの流れを可視化できるよう命名・構造化
結語
Chain of Responsibility パターンは、処理を段階的に分離し、
それぞれの責務を独立したハンドラとして定義することで、
動的な処理フローを構築できる構造的アプローチである。
- 条件分岐からの脱却
- 柔軟なパイプライン構築
- 動的ルーティングやイベント処理との親和性
Pythonicとは、“流れを設計可能な構造で表現する”ことであり、
Chain of Responsibility はその思想を、可変的かつ拡張可能な形で実現する設計である。