SOLID原則をざっくり理解する

2024/04/09に公開

後輩がもうすぐできるがSOLID原則について説明できるほど理解できてなかったので、後輩に教えられるようにSOLID原則を出来るだけシンプルにまとめてみた。

そもそもSOLID原則とは

ソフトウェア設計をより平易かつ柔軟にして保守しやすくするために遵守するべき5つのガイドラインのこと。

S (Single Responsibility) 単一責任の原則

モジュールやクラス、関数は単一の機能について責任を持つべきであるという原則。
読んで字の如くなので分かりやすい。

なぜそうするべきか?

複数の機能を持っているとそのモジュールやクラス、関数が何を行っているのかが分かりにくくなってしまうから。

O (Open-Closed) オープン・クローズドの原則

既存の処理に変更が発生した場合、既存のロジックに手を加えなくても新しいロジックを追加するだけで変更ができる設計になっているべきであるという原則。

つまり、クラスは拡張にはオープンで、変更にはクローズドであるべきだということ。

なぜそうするべきか?

既存のロジックに手を加えてしまうとそのクラスを使用している全ての箇所でバグを生むリスクが高まるから。

L (Liskov Substitution) リスコフの置換原則

親クラスと同様の振る舞いを子クラスでもできるように設計するべきという原則。
つまり、親クラスを使用している部分を子クラスで置き換えても問題なく動作するようにするべきであるということ。

決して親クラスのメソッドをオーバーライドするな、ということではなく、子クラスを作成するときは下記を遵守するべきだということ。

  • 事前条件(メソッド開始時に保証されるべき条件)は親クラスと同等かより緩く設定する
  • 事後条件(メソッド終了後に保証されるべき状態)は親クラスと同等かより厳しく設定する

深掘ると奥が深いが、詳しくは下記が分かりやすい。
【SOLID】リスコフの置換原則を完全に理解したい

なぜそうするべきか?

親クラスと子クラスで振る舞いが一貫していた方がそれらのクラスでできることが明確になり、コードの保守性が高いから。

一方、親クラスと子クラスで振る舞いがバラバラだと、それらのクラスを使うには全ての振る舞いを考慮しなければならないため、コードの保守性が低下する。

I (Interface Segregation) インターフェイス分離の原則

インターフェースの継承先で不要な処理が作られないようにインターフェースを分離するべきであるという原則。

インターフェースを継承すると、継承先では継承元インターフェースが持つメソッドをもれなく全て実装しなければならない。
しかし、継承先で使用する必要がないメソッドをわざわざ実装する意味はない。
そのため、無意味なメソッドを作らないようにインターフェースを分け、継承元として必要なインターフェースのみピックアップして継承するべきであるということ。

なぜそうするべきか?

使わない処理が実装されているとコードの可読性・保守性が低下するから。

D (Dependency Inversion) 依存性逆転の原則

ある上位モジュール内で下位モジュールを使う際、上位モジュールは下位モジュールに依存すべきではなく、上位モジュールと下位モジュールのいずれも抽象に依存させるべきという原則。

抽象に依存するような実装方法の詳細や、なぜ上位モジュールと下位モジュールの依存性がなぜ逆転するようになるのかは割愛するが、下記記事が分かりやすい。

依存性の逆転のいちばんわかりやすい説明

なぜそうするべきか?

モジュール同士の結合度を低くできるから。
モジュール同士の結合度が低いとモジュール同士を簡単に切り離せる。

つまり、下位モジュールを参照する際にはインターフェースを参照しているので、もしこの下位モジュールの処理に変更が生じた場合でも新しく作成した別のモジュールを元のインターフェースに紐づけるだけで変更できるため、変更に強い設計になる。

参考文献

Discussion