5-7
メソッドチェーンで掘り進まない(尋ねるな、命じろ)
a.b.c.d と内部構造を掘り進んで値を読み書きすると、呼び出し側が相手の内部実装に深く依存する。構造を1つ変えただけで全呼び出し元が壊れ、同じ判定や更新ロジックがあちこちに複製される。内部を尋ねて自分で判断するのではなく、やってほしいことをメソッドとして命じる。
経費精算の承認と予算消化
✕ Bad
# 承認画面のハンドラ
if report.applicant.department.budget.remaining >= report.amount:
report.applicant.department.budget.remaining -= report.amount
report.status = "approved"
# 別の画面にも同じチェーンと判定ロジックのコピーが…
# budget の構造を変えると全呼び出し元が壊れる✓ Good
class DepartmentBudget:
def __init__(self, remaining: int) -> None:
self._remaining = remaining
def spend(self, amount: int) -> None:
if amount > self._remaining:
raise ValueError("部署予算の残高を超えています")
self._remaining -= amount
class ExpenseReport:
def approve(self, budget: DepartmentBudget) -> None:
budget.spend(self.amount) # 尋ねず、命じる
self._status = ReportStatus.APPROVED
report.approve(budget)「知らない相手のさらに知り合いに話しかけるな」というデメテルの法則の考え方。チェーンが長いほど依存が深い。この「尋ねるな、命じろ」はメソッド設計の章(第12章)でも別の角度から再登場する。