密結合
8-4

Util クラスへの依存を断つ

置き場所に迷った処理が「とりあえず Util へ」と放り込まれると、互いに無関係なデータとロジックが1つのクラスに同居する。各インスタンス変数が特定のメソッドからしか使われていないなら、それは複数のクラスが1つに押し込められているサイン。変数ごとに切り出せば、それぞれが単体で意味を持つクラスになる。

バックオフィス処理の寄せ集めクラス

Bad

請求書・月次レポート・支払リマインダーという無関係な3つの関心事が同居している

なんでも入りの Util クラス
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 されるため、一度肥大化すると全モジュールと密結合になる。「どのデータをどのメソッドが使っているか」の対応を見れば、分割線は機械的に引ける。

参考: 『良いコード/悪いコードで学ぶ設計入門』(ミノ駆動 著、技術評論社)第8章。コード例は原則を自分の題材で表現し直したオリジナル。
8-4

Util クラスへの依存を断つ

置き場所に迷った処理が「とりあえず Util へ」と放り込まれると、互いに無関係なデータとロジックが1つのクラスに同居する。各インスタンス変数が特定のメソッドからしか使われていないなら、それは複数のクラスが1つに押し込められているサイン。変数ごとに切り出せば、それぞれが単体で意味を持つクラスになる。

バックオフィス処理の寄せ集めクラス

Bad

請求書・月次レポート・支払リマインダーという無関係な3つの関心事が同居している

なんでも入りの Util クラス
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 されるため、一度肥大化すると全モジュールと密結合になる。「どのデータをどのメソッドが使っているか」の対応を見れば、分割線は機械的に引ける。

参考: 『良いコード/悪いコードで学ぶ設計入門』(ミノ駆動 著、技術評論社)第8章。コード例は原則を自分の題材で表現し直したオリジナル。