オープン・クローズドの原則

参考:

SOLIDの原則ってどんなふうに使うの? 〜オープン・クローズドの原則編(拡大版)〜 - Speaker Deck

オープン・クローズドの原則の定義

オープン・クローズドの原則とは

  • 「Open」「Closed」を同時に満たすこと
    • 「Open」とは、機能を拡張できること
    • 「Closed」とは、修正を行わないこと

オープン・クローズドの原則を使用する理由

SOLIDの原則が目指している「良い設計」をもっとも反映しているから

  • なぜ、そう言えるのかは割愛

    バリエーションからコードを守ることに長けているから

オープン・クローズドの原則の使い方

問題の分析

  • 問題を見つけるための着眼点
    • バリエーションによって変更される部分を探す
    • バリデーションを増やすことが容易かどうかを想定する
  • 問題かどうかの指標
    • 変更されるだろう部分がバリエーションの軸に沿ってまとめられているかを確認する
    • バリデーションを増やした際に、OPCを破るなら改善する必要がある

      改善方法

  • バリエーションの軸を捉え直す
    • 既存の軸で変更範囲が甚大ならば、他の軸を見つける
  • 一番おおもとのバリエーションごとに分けられる軸に沿わせる
    • それぞれでクラスを作る
    • それがバリエーションで分けるということである
  • 条件分岐を各バリエーション自身に任せる
    • 使う側がどの処理をやるかを決めるのではなく、バリエーション自身に決めさせる
    • バリエーションの判定をResolverクラスに任せる
      • Resolverクラスには、それぞれの種類のコードは出てこない
      • バリエーションがあるクラスに共通のメソッドを持たせる
      • そのクラス自身に処理を決めさせる

具体的なコード例

問題点①: バリエーションが増えると増やすとバラバラにコードを書き足す必要がある

  • 問題の分析
    • コードの現状の軸とバリエーションの増加する可能性がある軸の整理
      • 現状採用している軸
        • 「行」のバリエーション
      • 増加するバリエーションから考えられる軸
        • 行の種類
        • TODOの種類
        • 出力フォーマットの種類
      • どのバリエーションが増加したときに変更が大きくなるのか
        • TODOのバリエーションが処理全体に大きな影響を与えそう
          • フォーマット用の既存コードを修正する必要がある
      • バリエーションを軸にまとまっていると言えるかどうか
  • 改善方法
    • Todoのバリエーションを軸にした設計に変更

      問題点②: Switch文による分岐部分で既存のコードに付け足しが必要

  • 問題の分析
    • 分岐されるバリエーションが増えれば、elsifを増やす必要がある
  • 改善方法
    • Resolverの導入
      • switch文の処理を代替するオブジェクト
      • 入力に対応した処理オブジェクトを返す
        • 入力値自らが自分の処理を決める
      • 特定の集合に対して、特定のクラスを使うという対応付け(マッピング)の仕組み