お久しぶりです、らべねこです。
私は今「アジャイルソフトウェア開発の奥義」という本を読んでいます。
その中のSOLID原則の部分がよく分からなかったので、私なりにまとめて理解したものをQiitaに投稿しています。
今回は第2回です。
第1回はこちら https://qiita.com/labeneko/items/3033c9a0fa0772a864c2
間違い等ありましたらご気軽にコメントください。
SOLID原則とは
多くの設計で用いられている考え方を原則としてまとめたものです
以下の5つの原則があります
S:SRP、単一責任の原則
O:OCP、オープン・クローズドの原則
L:LSP、リスコフの置換原則
I:ISP、インタフェース分離の原則
D:DIP、依存性逆転の原則
第2回は、オープン・クローズドの原則についてまとめました
O:オープン・クローズドの原則(OCP: Open-Closed Principle)
守るべきルール
ソフトウェアの構成要素(クラス、モジュール、関数など)は拡張に対して開いていて、修正に対して閉じていなければならない
ルールを守らないとどのような問題が起きるか
- プログラムのちょっとした変更でさえ、その箇所と依存関係を持つすべてのモジュール(機能)に影響を与えてしまいます
「拡張に対して開かれている」とは
- モジュールの振る舞いを拡張できるということ
- 仕様変更に対して、モジュールに振る舞いを追加することで対処できます
「修正に対して閉じている」とは
- モジュールの振る舞いを拡張しても、そのモジュールのソースコードやバイナリコードは全く影響を受けないということ
具体的にどのような実装をすれば良いか
- モジュールを、ある固定した「抽象」に従属させます
- 「汎用的な機能と、その機能の具体的な実装を明確に分離する」ということ
- こうすることでコードを修正しなくても、その「抽象」の派生クラスを新たに追加するだけで振る舞いを拡張できます
- デザインパターンで言う StrategyパターンとTemplate Methodパターンの2つがOCPに準ずるために利用される最も典型的なパターン
落とし穴
- せっかくOCPに準じた変更に強い実装を行っていても、次に来る仕様変更には弱いということがよくあります
- 抽象化しないほうが良かったという場合すらあります
- そのような仕様変更が起きることを先に見越していればよいのだが、そのようなことは無理です
- また、「すべてのケースに適用できる自然なモデル」は存在しません
- 実装者は、今後の仕様変更を予測することになる。正しく推測できれば勝者で、間違ったら敗者だが、大体の場合は間違えます
最初の仕様変更には騙される
- 今後を予測して実装するということは、ソフトウェアに不必要な複雑さを導入してしまうことになります
- そこで、最初は変更が起きないことを前提にコードを書き、最初の仕様変更時に抽象を導入するようにする。そして、同様の仕様変更には耐えられるようにしておきます
最初の仕様変更を促す
- 最初の仕様変更は、早い段階で飛んできてくれたほうがありがたいでしょう。したがって、以下のようなことを行います
- 短いサイクルで開発する
- 最も重要な機能から優先的に開発する
- 早期かつ頻繁にソフトウェアをリリースし、出来るだけ早くかつ頻繁に顧客やユーザに提示する
結論
- OCPは、オブジェクト指向設計の核心であり、オブジェクト指向設計から得られる最大の利益を享受できます
- しかし、不必要な複雑さを生み出すことにもなるので、無闇に使えば良いわけではありません
- 最も頻繁に変更されるプログラム部分にだけ的を絞って抽象を適用し、早まった抽象をしないことも、抽象を使うのと同じぐらい大事なことです
第3回では、リスコフの置換原則について説明します
(らべねこしか分からないSOLID原則になっていたらごめんなさい…)