Edited at

コンポーネントに関する6つの原則

More than 1 year has passed since last update.


コンポーネントとは

コンポーネントとは、デプロイ単位のことであり、システムの一部としてデプロイできる最小限のまとまりを指す。例えば、Javaならjar、Rubyならgem、.NETならDLL等がそれにあたる。あらゆる言語において、コンポーネントがデプロイの基準となる。よくできたコンポーネントは常にデプロイできる状態を保っているため、個別に開発を進めることができる。

本記事では「コンポーネントの凝集性に関する原則」3つと「コンポーネントの結合に関する原則」3つを取り上げる。


コンポーネントの凝集性に関する原則

凝集性とは、機能と機能の関わり具合の尺度を指す。凝集性が高い(機能と機能の関わり具合が低い)ほど良いプログラムとされる。

※密接に関係するものは1つに集め、関係しないものは分けるという考え方がベースとなる。


再利用・リリース等価の原則(REP:The Reuse/Release Equivalence Principle)

「コンポーネントを再利用するには、コンポーネントのリリース単位で行う」という原則。

言い換えると「再利用の単位とリリースの単位は等価になる」という原則。

※例えば、Javaのクラスを修正した場合、クラス単位ではなくjar単位でリリース・再利用を行うのが理想。

考え方としては重要なのは「コンポーネントに含まれるクラスは、すべてが再利用されるか、すべてが再利用できないかのどちらかにすべき」ということ。


閉鎖性共通の原則(CCP:The Common Closure Principle)

「同じ理由、同じタイミングで変更されるクラスをコンポーネントにまとめること。変更の理由やタイミングが異なるクラスは、別のコンポーネントに分ける」という原則。

これは、単一責任の原則(SRP)をコンポーネント向けに言い換えたもので「コンポーネントを変更する理由が複数あるべきではない」としている。変更箇所が1つのコンポーネントに閉じていれば、変更後にデプロイする必要があるのはそのコンポーネントだけになり、そのコンポーネントに依存していないコンポーネントは再デプロイは不要となる。

考え方としては重要なのは「同じ理由、同じタイミングで変更されることが多いクラスは1つのコンポーネントにまとめておくべき」ということ。


全再利用の原則(CRP:The Common Reuse Principle)

「1つのクラスだけを再利用するということはめったになく、複数のクラスと組み合わせて使われることがほとんどのため、そうしたクラス群は1つのコンポーネントにまとめる」という原則。

この原則は、どのクラスをひとまとめにすべきかということと、どのクラスをひとまとめにすべきではないかを表現している。


コンポーネント凝集性のテンション図

各原則は相反するところがあるため、アーキテクトはこれらの原則をバランスよく取ること。

テンション図.png


コンポーネントの結合に関する原則


非循環依存関係の原則(ADP:Acyclic Dependencies Principle)

「コンポーネントの依存グラフに循環依存があってはならない」という原則。

コンポーネント間で循環依存がある場合、コンポーネント単独でのデプロイ、リリースができずその部分が温床となりコンポーネント間での不整合が発生する。そのため(アプリケーションが成長するにつれてコンポーネントの依存構造も細かく変わっていくので)、循環依存が生まれないよう適切に管理する必要がある。なお、コンポーネント間での依存は、具象クラスレベルではなく、インターフェース等の抽象レイヤーで依存すること。


安定依存の原則(SDP:Stable Dependencies Principle)

「安定度の高い方向に依存すること」という原則。

「安定度の高い」とは、変更がしづらいということ。多数のコンポーネントから依存されたコンポーネントは(変更することの影響が大きいので)変更しづらい、そのためこういったコンポーネントは安定度が高いと考えらえれる。また、基本的に抽象度の高いレイヤーに依存すべきなため、「安定度の高い方向に依存」とは、言い換えると抽象度の高いレイヤーに依存せよとも言える。


安定度・抽象度等価の原則(SAP:Stable Absstractions Principle)

「コンポーネントの抽象度は、その安定度と同程度でなければならない」という原則。

つまり、安定度の高いコンポーネントは抽象度も高くあるべきで、安定度の高さが拡張の妨げになってはいけない。一方、安定度が低いことによってその内部の具体的なコードが変更しやすくなるため、安定度の低いコンポーネントはより具体的であるべきである。


参考

Clean Architecture 達人に学ぶソフトウェアの構造と設計