ソフトウェアの品質（結合度）って？？

# 背景
ソフトウェアの結合度について復習したことを備忘録として残しておく。
[凝集度について調べた記事へのリンク](https://qiita.com/issykatsu/items/e8c1b4acc7bd30dda32d)


目的：モジュール・クラス設計の根拠を説明するときに、
「結合度がxxxなので、こちらの設計のほうがより良いと考えました」と **当たり前のように** 説明できる。

# 参考文献

* [1] [組込みソフトウェア開発のための オブジェクト指向モデリング (組込みエンジニア教科書)](https://www.amazon.co.jp/組込みソフトウェア開発のための-オブジェクト指向モデリング-組込みエンジニア教科書-SESSAME-WG2/dp/4798111767/ref=sr_1_1?__mk_ja_JP=カタカナ&crid=1OV6K2TYW6H06&keywords=オブジェクト指向モデリング&qid=1672325264&sprefix=オブジェクト指向モデリング%2Caps%2C223&sr=8-1)
* [2] [実践UML―パターンによるオブジェクト指向開発ガイド](https://www.amazon.co.jp/実践UML―パターンによるオブジェクト指向開発ガイド-クレーグ-ラーマン/dp/4894710773/ref=sr_1_1?__mk_ja_JP=カタカナ&crid=2IATC870ZLBZT&keywords=実践UML+パターンによるオブジェクト&qid=1672904042&sprefix=実践uml+パターンによるおぶじぇくと%2Caps%2C219&sr=8-1)

# 結合度（カップリング）
ひとつのクラスが他のクラスに対し、どの程度の強さで接続するか、把握するか、あるいは依存するかを示す尺度。

参考文献の[1]では以下のように定義されていました。

1. データ結合
1. 構造体結合
1. バンドリング結合
1. 制御結合
1. ハイブリッド結合
1. 共通結合
1. 内容結合 

ただ、色々ネットで調べてみると、以下のような結合度が定義されていました。どれが正式な定義なのか、、
違うのはメッセージ結合の有無と、構造体結合・バンドリング結合をスタンプ結合としているところ、外部結合とハイブリッド結合の呼び方の違いです。

ネットでは以下のほうが多かったのでこちらで考えるようにします。

1. メッセージ結合： 引数のない関数の呼び出しで結合
1. データ結合： スカラ型の値で結合
1. スタンプ結合： 構造体やクラスで結合
1. 制御結合： 制御フラグで結合
1. 外部結合： 共通の単一グローバル変数で結合
1. 共通結合： 共通の複数のグローバル変数で結合
1. 内容結合： 宣言されていない変数での結合

クラス同士の依存関係が密（あるいは強い）だと、多くのクラスに依存するので、以下のような問題がある。
* 関係するクラスになされた変更によって局所的な変更が必要になる
* 分離して理解することが難しい
* そのクラスを仕様するにはそのクラスが依存するクラスも取り出さなければならないため、再利用しにくい

なので、依存関係をできるだけ疎にする必要がある。

## メッセージ結合
引数のない関数の呼び出しで結合。

![ドラえもん_凝集度-結合度_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/60dc6b51-764e-7a34-8f84-01ff9e9b77f0.jpeg)

ドラえもんはタケコプターに飛行というメソッド呼び出しのみ（戻り値もなし）

## データ結合
モジュール間の情報伝達が、純粋なデータだけであること。

![ドラえもん_凝集度-結合度_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/d811d13a-d205-0b6a-0ece-e17336ef66d5.jpeg)

目的地というデータだけを引数で渡していて、ひとつの出力をもらっている。
## スタンプ結合（構造体結合、バンドリング結合）
ある構造を持ったデータ群のことであり、いわゆる構造体データで結合している。

※構造体というデータ構造自身が、同じ目的を持っているメンバ群で構成されていれば特に問題はない。
2つのモジュール間で、複数のデータを知っていることが前提であるため、データ結合よりは依存度は高い。

バンドリング結合は、Bundleという言葉が使われているように、さまざまなデータを復路に入れて渡しているイメージです。
※バンドルされたデータ群が意味のあるまとまりであればカップリングは弱く、意味のないデータ群であればカップリングが強くなる。

![ドラえもん_凝集度-結合度_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/f2d50979-2373-1b0f-2050-1ff94ca6bce3.jpeg)

秘密道具という構造体の中に、どこでもドア用のデータ（目的地）がある例です。

## 制御結合
データではなく、何らかの制御を意図した情報が伝達される。
典型的なのは、フラグを渡すような場合です。フラグを相手のモジュールに渡すということは、開いての内部制御に対して指示を出していることになり、依存関係は比較的強い。
とりうるパターンが引数に依存している結合。

![ドラえもん_凝集度-結合度_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/f6e1ae60-eedb-609f-ac0b-4c9a217cc951.jpeg)

どら焼き買い出しマシーンのメソッドの引数に「行動パターン」を渡していて、
渡す「行動パターン」によっては、どら焼きを買うだけではなく、通帳記帳もするように、
制御に影響を与えることができます。

## 外部結合（ハイブリッド結合）
※書籍とネットで定義が揺れている

* 共通の単一グローバル変数で結合
* 必要なデータだけを外部宣言し、他のモジュールから参照を許可し、共有する
* 外部から供給されたデータ·フォーマット、通信プロトコル、またはデバイスインターフェイスを共有している場合に起こる。 これは基本的に外部ツールやデバイスへの通信に関連している。
* 値の範囲によって複数の意味を持つデータ（ハイブリッド結合）

![ドラえもん_凝集度-結合度_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/06084bab-0472-eecf-ce86-bd2503cfb020.jpeg)

「どら焼き買い出しマシーン」と「どらえもん」がグローバル変数の「どら焼き」を見ている。
「どらえもん」か「どら焼き買い出しマシーン」を修正すると、
「どら焼き」に影響を与えるので、
もう一方も修正しないといけない可能性がある。

## 共通結合
※書籍とネットで定義が揺れている

* グローバルデータによる結合です。
つまり、お互いのモジュールが共通にアクセスできるデータ領域を利用する結合です。
* 共通の複数のグローバル変数で結合


![ドラえもん_凝集度-結合度_6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1878269/b62d3dbc-eb0d-6943-c25b-1769594f96ca.jpeg)

「どら焼き買い出しマシーン（改）」はグローバル変数の「どら焼き」「ママの通帳」のどちらも参照しているため、結合度が高い。

## 内容結合
アセンブラでしか書けないであろう、モジュールの途中から呼び出すような結合。gotoがある言語ではできる。
高級言語を使っていればコンパイラが許してくれないので割愛します。

# まとめ
結合度についても、一概に「メッセージ結合」「データ結合」でないといけない！などは言えないので、
結合度を意識して設計できるようにしていこうと思います。

凝集度と結合度も合わせて、設計品質検証のポイントを以下に示す。

| 内容 | 見るポイント |
|:-:|:-:|
| クラスの責務は明確か？  | クラスのサイズ（属性度）、責務のコヒージョン  |
| 役割分担は適切か？  | セマンティックの重複、責務のカップリング、クラスから出る関連の数、多重度 |
| クラスの数は適切か？  | モジュール内のクラス数 |
| 責務が階層化されているか？ | 責務コミュニケーション図の形 |
| クラスの抽象度は適切か？  |  モデルの分かりやすさ、モデル化の指針 |