SOLIDが語り継がれる理由

原則というものは便利だ。自分自身の設計をブレさせるだけでなく、他人とアーキテクチャを議論する上でも役に立つ。POSTDでも取り上げられたSOLID原則について、原文も眺めてみよう。

Single Responsibility Principle
A class should be responsible for only one thing. If a class has more than one responsibility, it becomes coupled. A change to one responsibility results to modification of the other responsibility.

クラスはひとつのことだけ責任を持つべき。一つ以上の責任を持っていると、ひとつの責任のchangeが他の責任のmodificationになってしまう。(POSTDではchangeもmodificationも「変更」と訳していたが)

原文では、プロパティの変更とデータベースの変更の両方をしているクラスは単一責任の原則に違反しているからデータベースに格納するためのクラスを分離するべきだと書いている。そういえばサンプルコードはTypeScriptだ。

Open-Closed Principle
Software entities(Classes, modules, functions) should be open for extension, not modification.

クラス、モジュール、関数は拡張に対してOpenで、変更に対してはCloseであるべき。サンプルコードがユニークで、if文で普通の客とVIPで異なる値引率を設定すると、あとでSuperVIPを加えるときに元のクラスへの変更が必要になるが、例えばJavaScriptのextendsで新しいクラスを追加すると元のクラスを変更せずに拡張できる。

class Discount {
   giveDiscount() {
       if(this.customer == 'fav') {
           return this.price * 0.2;
       }
       if(this.customer == 'vip') {
           return this.price * 0.4;
       }
   }
}
class VIPDiscount: Discount {
   getDiscount() {
       return super.getDiscount() * 2;
   }
}
Liskov Substitution Principle
A sub-class must be substitutable for its super-class

サブクラスはスーパークラスにsubstitutable(代用可能)でなければならない。名前もわかりにくいが、中身もわかりにくいのでスルー。

Interface Segregation Principle
Make fine grained interfaces that are client specific
Clients should not be forced to depend upon interfaces that they do not use.

クライアントに固有のfine grained(細かい粒度)のインタフェースを作ること。クライアントは使わないインタフェースに依存しないべき。

多くのメソッドを含むクラスを継承しながら、使えるメソッドを限定させようということだ。

Dependency Inversion Principle
Dependency should be on abstractions not concretions
A. High-level modules should not depend upon low-level modules. Both should depend upon abstractions.
B. Abstractions should not depend on details. Details should depend upon abstractions.

依存性のInversion(逆転)の原則。依存性はconcretion(具体化)ではなくabstraction(抽象化)でなければいけない。

高レベルモジュールは低レベルモジュールに依存してはいけない。httpのgetのようにアプリが使う粒度のモジュールを高レベル、httpserviceのように細かい粒度のモジュールを低レベルとすると、伝統的な設計では高レベルのモジュールが低レベルのモジュールに依存する。DIPは「逆転」とは書いてるが、下の図(Wikipediaで見つけた)のように抽象レイヤを設ける。

Derick ends with stating that if you have large monolithic chunks of code in your system, SOLID will help you break these into individual pieces. It will not decrease complexity, but will help you create abstractions and group details into larger concepts that we can reason about.

InfoQではDerick BaileyがSOLIDについて「large monolithic chunkをindividual pieceに分割することを助ける」と紹介した。複雑さを減らすことはないが、reason(論理的に考える)ができるよう大きな概念にグルーピングすることができる。

SOLIDって単なる語呂合わせかなと思っていたが、順序も理解しやすい順に並んでいて、最後のDIPが最も理解が大変ながらも、メッセージ性が強い。だからこそ根強く語り継がれているのかもしれない。


この記事が気に入ったらサポートをしてみませんか?