SOLID

SOLID（ソリッド）は、ソフトウェア工学の用語であり、特にオブジェクト指向で用いられる五つの原則の頭字語である。ソフトウェア設計をより平易かつ柔軟にして保守しやすくすることを目的にしている。その特徴はインターフェースを仲介にしての機能の使用と、インターフェースによる機能の注入である。

この五つの原則は、アメリカのソフトウェア技術者ロバート・C・マーティン（英語版）が提唱していた数々の設計原則の中からチョイスされたものである。マーティンが提唱していた原則は、例えば2000年に発表されたレポート『Design Principles and Design Patterns』[1]の中で紹介されている[2][3][4]。そのうち五原則をSOLIDという語呂合わせの頭字語にして普及させたのは、ソフトウェア技術者マイケル・フェザーズであり、2004年以降に広く知られるようになった[5]。SOLIDはオブジェクト指向設計由来であるが、アジャイルソフトウェア開発や適応的ソフトウェア開発（英語版）といった方法論の哲学にもなっている。

## 五つの原則

[編集]

SOLIDは、次の5つの原則からなる。

* 単一責任の原則 (single-responsibility principle)
* 開放閉鎖の原則（open/closed principle）
* リスコフの置換原則（Liskov substitution principle）
* インターフェース分離の原則 (interface segregation principle)
* 依存性逆転の原則（dependency inversion principle）

### 単一責任の原則 (single-responsibility principle)

[編集]

> There should never be more than one reason for a class to change.[6]（→変更するための理由が、一つのクラスに対して一つ以上あってはならない）

これは、every class should have only one responsibility.（→各クラスはそれぞれ一つだけの責務を持つべきである）とも言い換えられる。ここでの責務とは提供機能と同義である。この原則は、clientに特定の機能を提供する役割（role）役者（actor）としてのserviceのクラスに焦点を当てている。

この原則下のserviceは、それぞれ一つの機能または一つの役割しか持てない。この原則下のclientは、機能別に担当serviceを変更することになる。

### 開放閉鎖の原則（open/closed principle）

[編集]

> software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.[7]（→ソフトウェアの実体（クラス、モジュール、関数など）は、拡張に対して開かれているべきであり、修正に対して閉じていなければならない）

この原則下のinterfaceはその構成が不変になり、serviceは構成の変化が許される。serviceの構成変化は、継承によるサブクラス定義でなされるのが普通である。

### リスコフの置換原則（Liskov substitution principle）

[編集]

> Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.[8]（→ある基底クラスへのポインタないし参照を扱っている関数群は、その派生クラスのオブジェクトの詳細を知らなくても扱えるようにしなければならない）

この原則下のclientは、一つのinterfaceを通して、様々なserviceクラスを利用することになる。

### インターフェース分離の原則 (Interface segregation principle)

[編集]

> Many client-specific interfaces are better than one general-purpose interface.[9]（→汎用なインターフェースが一つあるよりも、各クライアントに特化したインターフェースがたくさんあった方がよい）

この原則下のinterfaceは、様々に機能分化されて細かな用途ごとに定義されることになる。

### 依存性逆転の原則（dependency inversion principle）

[編集]

> High-level modules should not import anything from low-level modules. Both should depend on abstractions (e.g., interfaces), [not] concretions.[10]（→上位モジュールはいかなるものも下位モジュールから持ち込んではならない。双方とも具象ではなく、抽象（インターフェースなど）に依存するべきである）

この原則は、Mix-inをモチーフにして依存性の注入などのベースになっている。

この原則下のclientは、専門機能が分離されたモジュールにされる。その下位モジュールは専門機能の扱い方を変えたものにされる。専門機能とは、clientがinterfaceを通して利用するserviceであり、上位clientと下位clientは共に、専門機能interfaceに依存することになる。ここでのclientは具象であり、interfaceは抽象である。

## 脚注

[編集]

1. ^ Robert C. Martin (2000年). “Design Principles and Design Patterns”. objectmentor.com. 2015年9月6日時点のオリジナルよりアーカイブ。2009年1月14日閲覧。
2. ^ Robert C. Martin. “Principles Of OOD”. butunclebob.com. 2014年7月17日閲覧。
3. ^ Robert C. Martin. “Getting a SOLID start”. objectmentor.com. 2013年8月19日閲覧。
4. ^ Sandi Metz (2009年5月). “SOLID Object-Oriented Design”. 2019年8月13日閲覧。 Talk given at the 2009 Gotham Ruby Conference.
5. ^ Fenton, Steve (2017). Pro TypeScript: Application-Scale JavaScript Development. p. 108\. ISBN 9781484232491. https://books.google.co.uk/books?id=ZEtADwAAQBAJ&pg=PA108
6. ^ “Single Responsibility Principle”. objectmentor.com. 2015年6月1日時点のオリジナルよりアーカイブ。2015年9月5日閲覧。
7. ^ “Open/Closed Principle”. objectmentor.com. 2015年9月5日時点のオリジナルよりアーカイブ。2015年9月5日閲覧。
8. ^ “Liskov Substitution Principle”. objectmentor.com. 2015年9月5日時点のオリジナルよりアーカイブ。2015年9月5日閲覧。
9. ^ “Interface Segregation Principle”. objectmentor.com (1996年). 2015年9月5日時点のオリジナルよりアーカイブ。2015年9月5日閲覧。
10. ^ “Dependency Inversion Principle”. objectmentor.com. 2015年9月5日時点のオリジナルよりアーカイブ。2015年9月5日閲覧。

## 関連項目

[編集]

* 依存性の注入
* GRASP
* コードの再利用
* パッケージの原則（英語版）
* Don't repeat yourself
* KISSの原則
* YAGNI（You aren't gonna need it）

* 表
* 話
* 編
* 歴

SOLID

* 単一責任の原則 (SRP)
* 開放/閉鎖原則 (OCP)
* リスコフの置換原則 (LSP)
* 依存性逆転の原則 (DIP)
* インタフェース分離の原則（英語版） (ISP)

* アジャイルソフトウェア開発
* デザインパターン