コンポーネントの原則について
コンポーネントとは
コンポーネント(Component)とは
コンポーネントとは、システムやソフトウェアの構成要素のことです。
これらは独立して機能しつつ、他の部分と組み合わせてシステム全体を構築することができます。
Componentとは英語で「部品、成分、構成要素」を意味します。
コンポーネントとモジュールの関係
IT用語として、コンポーネントと似た意味でモジュール(module)という言葉があります。
これらはほぼ同じ概念で用いられますが、若干意味合いが異なります。
コンポーネントは、システムの構成要素という意味であり、モジュールより広義な意味での部品を指します。
モジュールは、ひとまとまりの機能を持った部品という意味であり、全体の中での部分的なプログラムを指します。
開発現場よりの意味合いとしては、モジュールは主にプログラム関係の部品を意味します。
コンポーネントはファイル・プログラム・物理装置などのシステムにおける部品を意味します。
コンポーネントの凝集性に関する原則
凝集性(ぎょうしゅうせい)とは
凝集性とは、コンポーネントのまとまり具合に関する指標のことです。
言い換えれば、機能と機能の関わり具合の尺度を指します。
凝集性が高い(機能と機能の関わり具合が低い)ほど、メンテナンス性が高く、良いプログラムといわれます。
なお、以下の3原則は、それぞれ相反するところがあるため、アーキテクトはバランスよく方針を選択する必要があります。
凝集性に関しても、システムやソフトウェアのユースケースにより良し悪しが変わりますので、最適化していくことが重要です。
再利用・リリース等価の原則(Reuse-Release Equivalence Principle:REP)
再利用・リリース等価の原則とは、「コンポーネントを再利用するには、コンポーネントのリリース単位で行う」という原則のことです。
言い換えれば、「再利用の単位とリリースの単位は等価になる」ということを示しています。
この原則は、あるクラスをどのコンポーネントにまとめるべきかを考える際の指針となります。
コンポーネントは一貫するテーマや目的があり、それを共有するモジュールを集めなければなりません。
これは、コンポーネントを形成するクラスやモジュールは、まとめてリリース可能でなければならないということになります。
具体的には、例えばJavaのクラスを修正した場合、クラス単位ではなくjar単位でリリース・再利用を行うということです。
閉鎖性共通の原則(Common Closure Principle:CCP)
閉鎖性共通の原則とは、「コンポーネントに含まれるクラスは、すべて同じ種類の変更に対して閉じているべきである」という原則のことです。
つまり、コンポーネントのクラスは同じ変更理由を持ち、結合度が低いものでなければならないということです。
この原則は、クラス設計における単一責務原則に相当しています。
・変更の理由が異なるクラスは別のコンポーネントに分けるべきである。
・同じタイミングで変更されるクラスは同じコンポーネントに含めるべきである。
全再利用の原則(Common Reuse Principle:CRP)
全再利用の原則とは、「コンポーネントのユーザーに対して、実際には使わないものへの依存を強要してはいけない」という原則のことです。
つまり、コンポーネントを利用する際に使わないクラスが出てくる場合、それは別のコンポーネントに含めるべきという方針になります。
全再利用とは、パッケージに含まれるクラスが全て一緒に再利用されるという意味になります。
つまり、使用されるクラスや機能だけを一つのコンポーネントにまとめ、使われないクラスや機能は別のコンポーネントに分けるべきという考えです。
これにより、無駄な依存関係が排除され、不要なデプロイを避けることが可能となります。
コンポーネントの結合性に関する原則
結合性とは
結合性とは、コンポーネント同士がどれだけ互いに依存し、影響し合っているかを示す指標のことです。
結合性が高い(密結合)と、あるコンポーネントを変更すると他のコンポーネントにも影響が及ぶ可能性が高く、保守性や拡張性が低下します。
結合性が低い(疎結合)と、コンポーネント同士が独立性が高く、変更の影響範囲が小さくなるため、保守性や拡張性が向上します。
非循環依存関係の原則(Acyclic Dependencies Principle:ADP)
非循環依存関係の原則とは、「コンポーネントの依存グラフに循環依存があってはならない」という原則です。
つまり、パッケージ間の依存関係は一方向になり、循環(依存関係のループ)を持ち込んではならないということ考え方です。
コンポーネント間で循環依存がある場合、1つのコンポーネントを変更したことで、依存関係のあるコンポーネントにも影響を与えます。
これは、修正影響を受ける箇所が拡大することになり、実施する必要のあるテスト範囲が増加することになります。
また、不具合発生時には、どこで原因で問題が発生しているのかを追跡するのが難しくなり、保守性が低下します。
循環依存を除去するには「インターフェースの導入」が効果的です。
コンポーネント間に抽象的なインターフェースを設け、依存の方向を一方向に統制します。
依存性逆転の原則(DIP)の適用を検討します。
安定依存の原則(Stable Dependencies Principle:SDP)
安定依存の原則とは 「コンポーネントの依存は安定度の高い方向に向く」という原則です。
ここでの「安定」とは、変更が起きにくいことを意味します。
つまり、多数のコンポーネントから依存されているような安定したコンポーネントに依存するように設計するということです。
一般的に、依存先のコンポーネントに変更が発生すると、それに合わせて変更を行う作業が発生する可能性があります。
そのため、依存先のコンポーネントは当該コンポーネントよりも安定しているべきである、という考えます。
安定度・抽象度等価の原則(Stable Abstractions Principle:SAP)
安定度・抽象度等価の原則とは、「コンポーネントの抽象度は、その安定度と同程度でなければならない」という原則です。
つまり、安定度の高いコンポーネントはその分柔軟性に欠けるため、抽象度を高くして拡張性を持たせるべきという考えです。
抽象度を高めるには、インターフェースや抽象クラスを使って開放閉鎖の原則(OCP)に則ることが効果的です。
抽象度の高いコンポーネントは、変更の可能性が少なくなるよう設計することが重要です。