CleanArchitecture - 「コンポーネントの凝集性」についてまとめる
CleanArchitecture 第13章「コンポーネントの凝集性」を簡単にまとめる。
コンポーネントとは
CleanArchitecture に簡潔に記載されているので、そのまま引用する。
コンポーネントとは、デプロイの単位のことである。システムの一部としてデプロイできる、最小限のまとまりを指す。Javaならjarファイル、Rubyならgemファイル、.NETならDLLなどがそれにあたる。コンパイル型言語ならバイナリファイル、インタプリタ型言語ならソースファイルになる。
CleanArchitecture 達人に学ぶソフトウェアの構造と設計 第12章「コンポーネント」
プログラミングにおける凝集とは
これはCleanArchitecture に記載はなかったのだが、そもそも凝集とは何なのかを正しく理解し、後の話の理解を容易にする。
凝集(ぎょうしゅう)という言葉の意味は
一か所にこり集まること
プログラミングでいうと
「各要素(クラス・モジュール・コンポーネント)の持つべき責任が1箇所に集中していること( = 一つの責務に集中すること)」
つまり、コンポーネントの凝集性とは
「システムの一部としてデプロイできる、最小限のまとまり( = コンポーネント)が一つの責務に集中する度合い」
と定義できそう。
3つの原則
コンポーネントの凝集性を考える際、下記の3つの原則が材料になる。
- 再利用・リリース等価の原則(REP)
- 閉鎖性共通の原則(CCP)
- 全再利用の原則(CRP)
コンポーネントはクラスやモジュールを適当に寄せ集めたものではなく、コンポーネントを形成するクラスやモジュールは凝集性のあるグループでなければいけない。
再利用・リリース等価の原則(REP)
再利用とリリースの単位は等価になる
等価でないとどうなるか。
- 再利用の単位がコンポーネントの単位より大きい場合
閉鎖性共通の原則(CCP)
同じ理由、同じタイミングで変更されるクラスをコンポーネントにまとめること。 変更の理由やタイミングが異なるクラスは別のコンポーネントに分けること。
単一責任の原則(SRP)をコンポーネント向けに言い換えたもの
- 単一責任の原則(SRP)
- クラスを変更する理由が複数あるべきではない
- 閉鎖性共通の原則
- コンポーネントを変更する理由が複数あるべきではない
変更箇所がひとつのコンポーネントに閉じていれば、変更後にデプロイする必要があるのはそのコンポーネントだけになる。
全再利用の原則(CRP)
コンポーネントのユーザーに対して、実際には使わないものへの依存を強要してはいけない
噛み砕いていうと、
コンポーネントを利用するユーザーが、コンポーネントを利用する際に、使わないクラスが出てくる場合、それは別のコンポーネントに含めようね
ということ。
考え方として大事なのは「不要なものに依存するな」ということ。
これは、もっと小さい単位でいうと「インターフェース分離の原則(ISP)」の「クライアントがインターフェースを実装した場合に、使わないメソッドがあるなら、それはインタフェース分けようぜ」である。
全再利用の原則(CRP) は「インターフェース分離の原則(ISP)」をコンポーネント向けに言い換えたものである。
コンポーネント凝集性のテンション図
上記3つの原則については、全部重要で全部遵守すべき、といったものではなく、相反している。
大きく言うと
- 再利用・リリース等価の原則(REP)
- 閉鎖性共通の原則(CCP)
はコンポーネントを大きくする方向に働き、
- 全再利用の原則(CRP)
はコンポーネントが小さくなる方向に働く。
3つの原則がそれぞれどのように影響するかを示すのが下記のテンション図。
CleanArchitecture 達人に学ぶソフトウェアの構造と設計 第13章「コンポーネントの凝集性」
ここで示しているのは、
- REP(再利用性のためのグループ化)を怠れば、再利用性が低下する
- CCP(保守性のためのグループ化)を怠れば、変更すべきコンポーネントが増加する
- CRP(不要なリリース作業を減らすための分割)を怠れば不要なリリース作業が増加する
ということ。
ここで重要なのは、
この3つの原則のバランスをうまくとることであり、バランスはその時の開発チームのフェーズによって変わってくる
ということである。
一般的に言うと、開発の初期段階は三角形の右側を重要視したほうがよい。
なぜならば、再利用性よりも開発しやすさのほうがが重要なため。
プロジェクトが始まって間もない頃に、書いたソースコードが再利用できるかどうか、なんて考える必要性はさほどない。
後期段階では、他のプロジェクトでの再利用を考えて三角形の左側が重要だと考えられることもあるだろう。
そういったように、開発チームのフェーズによってこの3つの原則の落し所を見つけるのが重要である。