🐞

SOLID原則メモ

2022/12/15に公開
名前 日本語 何がダメか? 改善方法
Single Responsibility 単一責任 1つのクラスに複数の機能を入れた クラス分割
Open Closed 開放閉鎖 あっちこっち変更しないといけない ストラテジーパターンなど
Liskov Substitution リスコフの置換 継承後にまったく違う機能にした 親クラスの方針を察する
Interface Segregation インタフェース分離 抽象クラスが複雑(とは?) 抽象クラスを分割
Dependency Inversion 依存関係逆転 クラスに依存 同じメソッドを持っていれさえすればいい

単一責任

1つのクラスに複数の機能を入れないようにしようという話

問題があるとされているコード
class Foo
  def a
    "機能A"
  end

  def b
    "機能B"
  end
end
  • Value Object などは典型的な良い例
  • この逆は神クラス
  • とはいえ分割しすぎるとクラス爆発してしまうのでバランスや効率の見極めが難しい

開放閉鎖

  • 解放 → 拡張しやすい
  • 閉鎖 → 拡張しても元のコードに影響がない

という話だけど逆に強迫観念に駆られないようにしたい。そうしないと際限がない。どこを拡張しやすくするか絞らないといくらでも拡張しやすくできてしまう。YAGNI原則から言えば拡張する必要が出てきてからやっと拡張しやすくするぐらいでよい

元のコード
class Player
  def roll
    3.times.collect { rand(1..6) }
  end
end
今すぐやる必要のなかったストラテジーパターン
class Dice
  def roll
    rand(1..6)
  end
end

class Player
  def initialize(dice)
    @dice = dice
  end

  def roll
    3.times.collect { @dice.roll }
  end
end

リスコフの置換

サブクラスを親クラスに置き換えても動かないといけない。そうしないと不整合が起きるから。例えば次のように文字列を返すと決まっているのに数値を返してはいけない

問題があるとされているコード
class Foo
  def to_s
    1
  end
end

──ということかと思ったが、SOLIDの図では「珈琲」を出すクラスのサブクラスで「水」を出すなと説明していてわりと主観的な内容だった

インタフェース分離

いまいちピンとこないけど関係ないもんを入れるなってことだと思われる

問題があるとされているコード
module NandemoHelper
  def x
  end

  def y
  end
end

# x を使いたいだけのクラスに y まで入っている
class A
  include NandemoHelper
end

たしかにそうだけど影響が出てから直すぐらいでいいんじゃないかな(小声)

依存関係逆転

問題があるとされているコード
class A
  def foo
    B.new.bar
  end
end

class B
  def bar
  end
end
  • 逆転とは?
    • 上のように A が B に依存している点を「逆転(してしまっている)」と表現し「依存関係(を)逆転(させてはいけない)」と主張しているのだと思っていたので混乱してしまった
    • まず A は B に依存しているので依存関係は A → B になる
    • そうではなく A → I ← B にしろと言っている
    • B に向かってくる矢印が逆になっている点を指して「逆転(させるべき)」と表現している
    • 体言止めよくない
  • I とは?
    • Java ではインターフェイスを指している。B にかますことで A から I っぽいやつを呼べるようになるという仕組みだけどダックタイピングな言語から見ればそもそも何の悩みがあったのかよくわからない
    • なので I は単に bar メソッドを呼べるもの と置き換えるとわかりやすい
  • 仰々しい名前がついているけど要は「クラスをハードコーディングしなければ融通が効く」というだけの話だった
  • また余計なことを書くとYAGNI原則により A が B しか使わないのであれば A → B で問題ない

参照

https://ja.wikipedia.org/wiki/SOLID
https://medium.com/backticks-tildes/the-s-o-l-i-d-principles-in-pictures-b34ce2f1e898

Discussion