ソフトウェア開発における原則
原則をまとめた記事は色々ありますが、これらを見ているだけだとどうにも理解ができなかったので、自分なりに落とし込んで記事にしてみました。
SOLID
オブジェクト指向プログラミングにおけるガイドライン
以下5つの原則の頭文字を取ってSOLIDの原則と呼ばれる
- SRP 単一責任の原則
- OCP オープン・クローズドの原則
- LSP リスコフの置換原則
- ISP インターフェース分離の原則
- DIP 依存性逆転の法則
SRP 単一責任の原則
クラスは単一の責任を持つべき
例えば、クラスがAとBという対象に責任を持ってしまっている場合、Aに対する挙動の修正が生じた場合、Bにも影響が生じてしまう。
A
-> クラス
B
そのため、クラスに対する責任は一つにして、他のアウターに対して影響が生じないようにする。
A -> Aクラス
B -> Bクラス
OCP オープン・クローズドの原則
クラスは拡張にはオープンで、変更にはクローズドであるべき
クラスに機能を加える際、コードを変更するのではなく、追加するような設計にするということ。
例えば、ABCという3つの機能を持つクラスABCに対して、Dという機能を追加しようとすると、クラスABCに対してDという機能を直接入れ込む形になってしまう。
そうなると、ABCの機能を使用している別のクラスに影響が生じてしまう。
クラスABC + D = クラスABCD
なので、クラスABCをそれぞれのクラスに分割、それらクラスに対してDのクラスを追加して、クラスABCDを作るようにする。
クラスABCD = クラスA + クラスB + クラスC + クラスD
結果的にクラスABCDが作られるのではなく、クラスABCDはクラスA,B,C,Dによって構成される形。
LSP リスコフの置換原則
子クラスは親クラスと同じ動作ができるべき
クラスから別のクラスを作る際にクラスが親になり、作成した新しいクラスが子クラスになる。これが継承。
子クラスが親クラスと同じ機能を有しない場合、子クラスを親クラスに置換した場合に大幅な変更が生じてしまう。
例えば、Aという機能をもった親クラス、Bという機能を持った子クラスがあった場合、Bを親にしたときにはAという機能を再実装する必要がある。
A, B -> B + A
そこで、同じ機能を有するように、子クラスにはAを拡張したA'という機能を持たせます。
A, A' -> A'
そうすることで、Bを親クラスにしてもAの機能は拡張されたA'によって実現される。
ISP インターフェース分離の原則
クライアントが使用しないメソッドへの依存を強制すべきでない
例えば、Bという機能をクラスに実装する際に、AとBという機能が定義されたインターフェースを継承していた場合、Aも実装しなければならなくなる。
IAB -> B + A
それを避けるために、インターフェースは可能な限り小さい単位に分離する。
IA, IB -> A, B
DIP 依存性逆転の法則
上位モジュールは下位モジュールに依存してはならない。それぞれ抽象に依存すべき
例えば、AがBに依存している場合、Bに変更が生じた時にAも修正しなくてはならない
A -> B
そこで、AをBの抽象に対して依存させることによって、Bが変更してもAの変更は最小限で済む
A -> IB <- B
AはBについての詳細は知る必要がない。
KISS
Keep It Short And Simple
簡潔に単純にする
コードはとにかくシンプルにする。
コードを複雑にすればするほど保守が難しくなるので、いかにシンプルに保つかが大事。
難しく書くことは簡単だが、簡単に書くことは難しい。
YAGNI
You Aren't Going to Need It
それはきっと必要にならない
コードは必要になってから実装する。
とりあえず…で実装したコードが活かされたケースはどれくらいあるのだろうか。(私の経験上、十中八九必要なかった)
むしろ、そのコードが存在することで技術的な負債になってしまうケースも少なくないと思う。
DRY
Don't Repeat Yourself
繰り返すな
同じコードは重複して書かない。
重複したコードは改善する際に重複するすべての箇所に手を加える必要が
あるので、できる限り処理を関数やモジュールにまとめるようにする。
ただし、過度なDRYは密結合になってしまったりと、逆によくない場合もあるのでなんでもかんでもDRYにすればいいってものでもない。
PIE
Program Intently and Expressivery
意図を表現してプログラミングせよ
コードは書いた意図を明確にしながら書く。
コードは書くことより読まれることのほうが多い。つまり、書きやすさより読みやすさを意識して書く。
参考
Discussion