8-4
Util クラスへの依存を断つ
置き場所に迷った処理が「とりあえず Util へ」と放り込まれると、互いに無関係なデータとロジックが1つのクラスに同居する。各インスタンス変数が特定のメソッドからしか使われていないなら、それは複数のクラスが1つに押し込められているサイン。変数ごとに切り出せば、それぞれが単体で意味を持つクラスになる。
バックオフィス処理の寄せ集めクラス
✕ Bad
class BackofficeUtil:
def __init__(self) -> None:
self.invoice_no = '' # 請求書番号
self.layout = ReportLayout() # 月次レポートの表示設定
self.reminder = ReminderPlan() # 支払リマインダー
def cancel_invoice(self) -> None:
... # invoice_no しか使わない
def switch_to_landscape(self) -> None:
... # layout しか使わない
def start_reminder(self) -> None:
... # reminder しか使わない✓ Good
class Invoice:
def __init__(self, invoice_no: str) -> None:
self._invoice_no = invoice_no
def cancel(self) -> None:
... # 請求書の取り消し
class MonthlyReport:
def __init__(self, layout: ReportLayout) -> None:
self._layout = layout
def switch_to_landscape(self) -> None:
...
class PaymentReminder:
def __init__(self, plan: ReminderPlan) -> None:
self._plan = plan
def start(self) -> None:
...Util クラスはあらゆる箇所から import されるため、一度肥大化すると全モジュールと密結合になる。「どのデータをどのメソッドが使っているか」の対応を見れば、分割線は機械的に引ける。