【ミライトデザイン社内勉強会#27】Clean Architecture 輪読会 「第4部：コンポーネントの原則」

# 第4部

### 参考
[Clean Architecture 達人に学ぶソフトウェアの構造と設計 | Robert C.Martin, 角 征典, 高木 正弘 |本 | 通販 | Amazon](https://www.amazon.co.jp/Clean-Architecture-%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E6%A7%8B%E9%80%A0%E3%81%A8%E8%A8%AD%E8%A8%88-Robert-C-Martin/dp/4048930656/ref=sr_1_1?adgrpid=121488233441&dchild=1&gclid=CjwKCAjwqIiFBhAHEiwANg9szoMKClJ8EAOZQYmJnaKQNiBAmHcmMwV4MyM3tMwvG83-ffR58lyKqRoCHVwQAvD_BwE&hvadid=499050245467&hvdev=c&hvlocphy=1009280&hvnetw=g&hvqmt=e&hvrand=2339268642175852705&hvtargid=kwd-1208075260070&hydadcr=21538_10997845&jp-ad-ap=0&keywords=%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3+%E6%9C%AC&qid=1621248524&sr=8-1)

### 前回の記事
[【ミライトデザイン社内勉強会#26】Clean Architecture 輪読会 「第3部：設計の原則」 - Qiita](https://qiita.com/tkek321/items/58f35dc64f5a87b5c955#%E5%8B%95%E7%9A%84%E5%9E%8B%E4%BB%98%E3%81%91%E8%A8%80%E8%AA%9E%E3%81%AE%E6%96%B9%E3%81%8C%E7%96%8E%E7%B5%90%E5%90%88%E3%81%AB%E3%81%97%E3%82%84%E3%81%99%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E3%81%AE%E3%81%8C%E3%81%82%E3%82%93%E3%81%BE%E3%82%8A%E3%83%94%E3%83%B3%E3%81%A8%E3%81%93%E3%81%AA%E3%81%84)

## 第12章 コンポーネント

### この章は、コンポーネントは個別にデプロイできる単位ってことと、コンポーネントができるまでの経緯が書かれているっていう認識
- コンポーネントは　[【ミライトデザイン社内勉強会#18】「IDDD本から理解するドメイン駆動設計」輪読会~第9章「モジュール」~ - Qiita](https://qiita.com/tkek321/items/2e89db963bd51e25fa1d#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E5%90%84%E5%8D%98%E8%AA%9E%E3%81%AE%E9%81%95%E3%81%84)　ここでいうモジュールやライブラリ、プラグインのイメージ

- そんな感じかなー
- phpのpharみたいなもんじゃない？Javaならjarファイルって書いてあるし
    - [https://www.php.net/manual/ja/book.phar.php](https://www.php.net/manual/ja/book.phar.php)

### コンポーネントって呼んでるのは、パッケージとかライブラリとかのことかな。
- デプロイできる単位っていうのは、外部ライブラリみたいに個別で利用できるとかそういう単位と思ったけど、p109の内容的にいろんな形式のことを指してるぽい
- OCPの話のときに、ControlerとかPresenterとかで分割した単位をコンポーネントって言っていたので（図8-2）、この本ではパッケージとかの単位のことを指してたりもする
    - とも思ったけど、Presenterとかの単位でもデプロイして外部公開ができたりするので、必ずしも1つのアプリケーションになっているとは限らないから、コンポーネントとはライブラリとかモジュールとか呼ばれている単位と認識して良さそう
- 歴史の箇所は正直あまり理解できてない
    - 昔はライブラリをアプリケーションに組み込んで一つのアプリケーションとしてコンパイルしていたけど、遅いしメモリの制限があったし時間がかかっていた。
    - そこから、ライブラリとアプリケーションを分離させることで個別にコンパイルできるようにしたとかそういう話の認識ぐらい
    - 今ではコンポーネントをアプリケーションにプラグインして使えるようになったよって書いてる章なのかな



### ちょっと極論かもだけど、AWS SQS とか AWS Aurora とかそれぞれをコンポーネントって思うといいかも？
- composer で入れてる Guzzle と PHPUnit とかもそうかも
- ムーア最強

## 第13章 コンポーネントの原則


### `コンポーネントの凝集度のテンション図`で閉鎖性共通の原則（CCP）が一つのコンポーネントを大きくする方向に働くものとして説明されているけど、単一責任の原則と閉鎖性共通の原則はどちらかというと大きなまとまりを役割ごとに小さくしていくイメージが強かった
- 関係あるものを集めて、関係ないことは分けようって話なので、場合によっては大きくなることもあるってくらいの温度感じゃないかな

### `コンポーネントの凝集度のテンション図` でCRPが不要なリリース作業を減らすための分割と説明されているけど、関連性の高いクラスが同じコンポーネントにまとまっていたらリリース回数が減るっていうのがイメージわかない
- 一つのコンポーネントに集まっていることで、コンポーネントが変更されたら使っている側のリリースが増えるって話だと思う
    - 使ってない機能のリリースの影響を受けてしまう
    - ここでいう回数は使う側の話だと思う
    - 使う側から見て必要のない機能に依存したくないっていうのがCCP
- 回数が減るっていうのは使ってる側の話


### コンポーネント=パッケージの認識だとREPの内容がよくわからない。
- パッケージをリリースできる単位にするっていうのと同じバージョン番号を共有するって話
- コンポーネントがライブラリとかの単位の話であればバージョンとかリリースドキュメントの話はなんとなく理解できる
    - おそらくこの章で言われているのは、リリースの単位っていうのがわかったのでしっくりきた気がする


### リリースとデプロイの意味は分けて理解しておいた方がいいよ
- デプロイだけだと、ユーザーに価値はない
    - デプロイは開発者が機能を使える状態にする
    - リリースはユーザーに価値を提供する
        - 何回かデプロイして、mainブランチが３回進む、それをまとめてユーザーに使ってもらうためにリリースするみたいな
    - デプロイの責任は開発者の責任、いつリリースするかはプロダクトオーナーの責任
- リリース
    - ユーザに価値提供する






### この本ではコンポーネントとリリースが 1 : 1 であるのがイケてると言っている
- それを破ってるのはどう言う状態か考えてみる
    - e.g. 1 : 2 ) SQS に新機能を作ったので SQS と Aurora をリリースしたよ、って言われる
        - SQS が裏で Aurora に依存しちゃってる
        - 「ハァ？ Aurora 使ってる箇所のテストやり直しやんけ！」
    - e.g. 2 : 1 ) SQS と Aurora に機能追加をしたので SQS をリリースしたよ、って言われる
        - Aurora の機能が SQS というコンポーネントに包含されてしまっている
        - 「ハァ？ Aurora の機能だけ取り入れることはできねーんスか？」
- コンポーネントとリリースが 1 : 1 じゃないと上記みたいなことが起こると思う


# 第14章 コンポーネントの結合

### `安定依存の原則（SDP）`ビジネスロジックみたいな重要なものを安定したコンポーネントにするんだよねきっと
- まぁそうかな

### `抽象コンポーネント` で`RubyやPyhonのような動的型付け言語には抽象コンポーネントは存在しない、依存性を逆転させるときに、何らかの宣言をしたり、インターフェースを継承したりする必要がないからだ` みたいなことが書いてるけど、インターフェースや抽象クラスのない動的型付け言語での依存性の逆転ってどうやんの？
- 動的型付け言語だと疎結合にしやすいっていうのが前提としてある気がする
    - [【ミライトデザイン社内勉強会#26】Clean Architecture 輪読会 「第3部：設計の原則」 - Qiita](https://qiita.com/tkek321/items/58f35dc64f5a87b5c955#%E5%8B%95%E7%9A%84%E5%9E%8B%E4%BB%98%E3%81%91%E8%A8%80%E8%AA%9E%E3%81%AE%E6%96%B9%E3%81%8C%E7%96%8E%E7%B5%90%E5%90%88%E3%81%AB%E3%81%97%E3%82%84%E3%81%99%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E3%81%AE%E3%81%8C%E3%81%82%E3%82%93%E3%81%BE%E3%82%8A%E3%83%94%E3%83%B3%E3%81%A8%E3%81%93%E3%81%AA%E3%81%84)
- Nominal Typing があるから動的型付け言語ではインターフェースを定義する必要がない
    - [https://ja.wikipedia.org/wiki/ダック・タイピング#:~:text=ダック・タイピング（英%3A duck,オブジェクトそのものが決定する。](https://ja.wikipedia.org/wiki/%E3%83%80%E3%83%83%E3%82%AF%E3%83%BB%E3%82%BF%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0#:~:text=%E3%83%80%E3%83%83%E3%82%AF%E3%83%BB%E3%82%BF%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%EF%BC%88%E8%8B%B1%3A%20duck,%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%9D%E3%81%AE%E3%82%82%E3%81%AE%E3%81%8C%E6%B1%BA%E5%AE%9A%E3%81%99%E3%82%8B%E3%80%82)

###  `安定度・抽象度等価の原則（SAP）`安定したコンポーネントは抽象度をあげて変更しやすくしなさい。不安定なコンポーネントは元々変更しやすいんだから抽象度をあげてもあんまり意味ないでしょっていう意味で理解をした
- あってんじゃない
- 無駄ゾーンは誰も使ってないクラス、誰も使ってないないということは何かを使ってしかないないから具体的じゃないと仕方ない

### SDP（安定依存の原則）は安定している = 変更がすくないという理解
    
- 変更が少ないというより、他から使われているから変更するのが大変なことになる状態を言う。変更をしずらい。安定していても変更する場合もある。
    - 昔hiroさんがtwitterでそんなこと言ってたな
    - [https://twitter.com/hirodragon112/status/1063490165870448640?s=20](https://twitter.com/hirodragon112/status/1063490165870448640?s=20)


```
@reoring

stability(安定性) → not easily moved (簡単には動かせない)


不安定: 彼氏が変わるたびに服が変わる
 → いろんな彼氏に依存している

=============================
@hiro

日本語的な(と言うか俺的な)印象として、『安定した』コンポーネントって表現より
『束縛された』コンポーネントって表現のほうがしっくり来るという結論を前に出したんだった。
```

### `SAP（安定度・抽象度等価の原則）` はドメイン知識を持っているクラスは、安定しているコンポーネントに配置するが、そうなると変更がしにくくなる。なので、抽象化して具象クラスを拡張していけるようにしようって理解。
- ドメイン知識という表現じゃなくて方針と表現した方が正しい
- コンポーネントの抽象化においては1クラスを抽象化するっていう話ではない。
- テンプレメソッドパターンとかストラテジパターンとかを連想する

### 本にはADP、SDP、SAPがなんの略なのか書かれてなかったから見つけてきた
[https://titanwolf.org/Network/Articles/Article?AID=3220eac2-0085-4e15-b414-def4f459bf21#gsc.tab=0](https://titanwolf.org/Network/Articles/Article?AID=3220eac2-0085-4e15-b414-def4f459bf21#gsc.tab=0)

- Acyclic Dependencies Principle
- Stable Dependencies Principle
- Stable Abstractions Principle

### 言語によっては循環依存してるとコンパイルできなかったりするよ

- Haskell だと循環 import をするとコンパイルができなくなる
    - Java とかは全然できる
- Haskell に慣れるまでは気づかないうちに結構やっちゃってよく怒られてた
- やっちゃってから直すのは大変だけど、自動で気づけるのはとても良いことだと思う

### 安定依存は`料金計算` と `通知` だと `通知` の方が変更見込みが低いので `料金計算 -> 通知` にするかっていう理解

- レイヤー単位で考えると、ドメインはシステム的な変更を知りたくないので最下位コンポ
    - つまり最も安定している
- 一番安定していたら一番変更しづらいということになってしまう
    - ドメインが一番変更し辛くていいのかってのが若干もやっとしてる

## 次回
[【ミライトデザイン社内勉強会#28】Clean Architecture 輪読会 「第5部：アーキテクチャ①」 - Qiita](https://qiita.com/tkek321/items/e66e5ffe15ee35057bb7)