凝集性と結合度についてまとめてみた

こんにちは、リンクアンドモチベーションの木村と申します。
昨年の4月に入社し、現在プロダクトのAPI開発を担当しています。
ほぼ未経験で入社したため、学びの整理が中心となります。
今回は、設計の重要概念である「凝集性」「結合度」についてまとめました。

参考書籍は「[良いコード／悪いコードで学ぶ設計入門](https://www.amazon.co.jp/%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%EF%BC%8F%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E5%AD%A6%E3%81%B6%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80%E2%80%95%E4%BF%9D%E5%AE%88%E3%81%97%E3%82%84%E3%81%99%E3%81%84-%E6%88%90%E9%95%B7%E3%81%97%E7%B6%9A%E3%81%91%E3%82%8B%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-%E4%BB%99%E5%A1%B2-%E5%A4%A7%E4%B9%9F-ebook/dp/B09Y1MWK9N/ref=sr_1_1?adgrpid=138030093569&dib=eyJ2IjoiMSJ9.H34fd9SNxzBRCdo5d3-jtRXNJaYKCB6BFKNtlYR9eOB_-_5dK-oYiZb6zghz5FzP6i4hE8UvGc_9bdymGR7esGFOmSnNH7E6Uu1KK4k5u5wD64QVjoC1sclzp3f03gEqT-K6HSCppFF7Nwkvz9Cw7xWgLln4Zxpk0FIXPNYXGIXB-Kz834_NFCxyV-KDr-VjWR7OM8UmnnUvd432QNDB-TOiM5oCroI2iDJB1xT8tm8.eSWcl2EtbVFCT6HboHdGHdx48GJtulQyXTJSykJRiIk&dib_tag=se&gclid=CjwKCAiAkp6tBhB5EiwANTCx1BKhcZ-BDl9aV5nmAAfbQ2o4FVZt3NRKTH7P8SXiqJjeioclEBYvABoCk6oQAvD_BwE&hvadid=651794682154&hvdev=c&hvlocphy=1009285&hvnetw=g&hvqmt=e&hvrand=13978909852170240768&hvtargid=kwd-1677064618724&hydadcr=23099_13622546&jp-ad-ap=0&keywords=%E3%81%84%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89+%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89&qid=1705496103&sr=8-1)」です。

結論、**高凝集・疎結合**な状態を目指そう！という話です。

# 凝集性と結合度について
## 凝集性とは
凝集性とは「**モジュール内における、データとロジックのまとまり度合い**」のことです。
モジュールはクラス、レイヤー、パッケージなど様々な粒度で扱われますが、高凝集な状態が理想的です。

### 凝集性が低い状態

凝集性が低い状態とは、機能や役割がバラバラに散らばっている状態のことです。この状態だと、変更に非常に弱い構造になってしまいます。例えば、数学的な計算をするメソッドが、データベースへのアクセスやログの記録も行う場合、凝集性が低いと言えます。

低凝集がもたらす具体的な弊害は以下の通りです。
- 重複コード
- 修正漏れ
重複コードの量産によって、修正する箇所に抜け漏れが出る可能性が高まります。
- 可読性の低下
コードの意図や処理の流れを素早く正確に理解することが難しくなります。見る人のエネルギーを消耗させる要因になります。

そのため、持続的にスムーズな開発を行なっていくためには、設計段階やリファクタリング時に適切に機能・役割でデータやロジックをまとめることが大切です。

## 結合度とは
結合度とは、「**モジュール間の依存の度合いを表す指標**」です。
ここで言うモジュールは、凝集性の説明で述べたように、様々な粒度を指します。ここでも、疎結合な状態が理想的です。

### 密結合な状態
密結合な状態とは、結合度が高い状態のことで、変更時に多くの影響範囲を考慮しなければならなくなる状態を指します。可能な限りモジュールを独立させ、依存関係を低めることが重要です。

## クラス設計で重要な原則
次に、クラス設計で重要な原則について2つ紹介します。
### 単一責任の原則
「一つのクラスには一つの責任のみを持たせるべき」という考え方です。
複数の責任を持つことにより、一方の変更が他方にも影響を及ぼし、バグの原因になることがあります。
そのため、クラスがどんな目的で、どんな役割を担っているのかを理解し、それに基づいて設計、実装を行うことが重要です。

### DRY原則
「同じことを繰り返さない」という原則です。
しかし、何でもかんでもまとめてしまうと密結合な状態になってしまいます。似たようなビジネスロジックでも、別の概念である場合があり、その場合は責務も別になるため、分離しなければなりません。この点には注意が必要です。
# イメージ
実装していない人にもなんとなくわかるように図を作ってみました。
### 実装対象の構成
ざっくり以下のような形になっていると思います。
![afbc9a59-c917-4c3b-30b9-31f7788f59dd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512663/97648717-9a05-fb7f-7243-434c2e0b65e5.png)


今回はクラスとメソッドを対象に考えます。
複数のクラスをうまく分け、目的・役割を明確にすることで「高凝集・疎結合」を実現できます。
![dd0f57f9-1472-950e-2fd2-d67feea90fd1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512663/97c5149c-c54e-152b-6486-83ffd5ceaff6.png)

### 疎結合な状態
![0f6bd53d-e486-1a33-e299-44e9ffccaa1c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512663/eee369e9-0013-02f3-5e78-da37f859faee.png)

### 密結合な状態
![55d6ae25-31b1-3edc-9f34-76c4520e9dd9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512663/191faf31-99ee-d758-f4ef-998aa1e9ca23.png)

### 低凝集な状態
これは結構わかりやすいです。
![902a9b6e-d653-ec35-dcee-2cd73111806d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512663/7e56b9e3-c538-2957-53fc-2bf9a81ac35e.png)

## まとめ
設計する際は、
- 同じ機能集団をまとめよう（高凝集）
- 機能集団の相互依存を減らそう（疎結合）

という点に注目しましょう。
自分はまだ実装経験が浅いので、まずイメージを作ることができてよかったです。
設計で考慮すべき点はまだまだ多いので、引き続き学習とアウトプットを行っていきたいと思います。