【ミライトデザイン社内勉強会#31】Clean Architecture 輪読会 「第6部：詳細」

### 参考
[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)


### 前回の記事
https://qiita.com/tkek321/items/10e281cfc632a1f8533d

# 第30章 データベースは詳細

- これはいろんなところで聞いているので理解できているつもり、ビジネスロジックに csv ファイルの形式が関係ないように、DB も関係しない

- データベースを使用しないでデータを使う場合ってどういうシステムがある?
    - 言ってみればデータベースもファイル
    - お問い合わせフォームの内容をcsvにして渡すとか
    - gitも.gitディレクトリに書き込まれてるし世の中にはいっぱいある
    
- Keycloak では本番環境では DB を使うけど、ローカルではいちいち DB を立てなくてもいいようにファイルシステムに保存するようになっている


- RDBMS がデータを行形式で持っているとかいうことはユースケースには関係ない
    - しかし多くのフレームワークは行をオブジェクトとして受け渡せるようになっている
    - これを安易に使うとユースケースから UI までが RDB の構造に縛られてしまう
- DB はデータをディスクからメモリに移動する仕組みにすぎないし、
メモリ上では好きなデータ構造にするべきだろう
- 重要なのはデータであり、データベースではない

- データベースは詳細でありビジネスルール側が依存すべきではない、というのはこれまでも書かれたとおり
- でも性能面の問題でUseCaseに変更が及んだことは結構ある。以前携わったプロジェクトだと1件ずつ `$repository→save()` してると終わらないのでbulk insert, bulk updateをするようにUseCaseの処理フローを変更することが結構あった。あのときはどう設計してたら分離できてたのかな？
    - 非機能に合わせるっていうのはどこまでいってもあるよね

# 第31章 ウェブは詳細

- この章では、 Web = View って認識であってるかな？
    - おそらくあってる
- これも良く聞く、 View は見た目に関することだけをしたほうがいい


- GUIはビジネスロジックから切り離して考えたりするっていうのは前の章からでも言われてたので、特に疑問点はなし

- バックエンドで計算するか、フロントで計算するかという話はいったり来たりしている事を振り子って表現してるのがわかりやすい


- 計算能力がどこに必要になるか定まらず、集中と分散の間を行ったり来たりし続けているが、その振り子は短期的な問題であり、ビジネスルールの中心からは切り離しておくべきだ
    - アーキテクトは長期的な観点で考える必要がある
- GUI is 詳細 かつ ウェブ is GUI なのだから、ウェブ is 詳細である
    - ウェブは入出力デバイスの一種でしかない

- WebはUI（GUI）と解釈すると、UIとビジネスロジックを分離したいのは自然な流れという感じがする
- とはいえWebでもデスクトップアプリでもスマホアプリでも切り替えられる、とするには分離するラインを見定めないと行けないのかな、という印象
- SPAとかって油断するとReactやVue側にビジネスロジックが書かれるので難しい


# 第32章 フレームワークは詳細


- フレームワークありきでの開発が長かったので、フレームワークと一定の距離を保つっていうのがまだ理解しきれてはいないかも。

    - ちゃんと書かれたコードを実際にみないとイメージつけるの難しそう
    - 僕は逆にバニラ PHP ( の訓練 ) から入りました



- フレームワークのリスク
    - 一般に依存性のルールに違反しがち
        - エンティティに組み込ませたがってくる
    - フレームワークの進化の方向が望みと一致しない可能性がある
    - 移植性が下がる ( 参考: [品質特性](https://webrage.jp/techblog/external_quality_inner_quality/) )
- 避けるには、フレームワークとは結合せず使うこと
    - 円の内側に入れてはならない
  

- フレームワークとビジネスオブジェクトを結合すると大変
    - 特にLaravelみたいな後方互換性のない進化を遂げるやつだと、結合すると大変そう
- ただあんまり分離しまくってCarbonとかCollectionみたいな便利な機能を全く使えないのも面倒といえば面倒（この辺はトレードオフ）
    - Carbon とかはただのライブラリだと思っていて、ビジネスロジックでも使ってもいいと思っている派
    - Carbon の腐敗防止のためにアダプターとして噛ませるのは全然あり
        - デザパタとかで使われるアダプターね
- 結婚という表現から考えれば、我々は経験豊富な仲人さんと言っても過言ではない

# 第33章 事例：動画販売サイト


- Catalog View と Catalog Presenter は2つのアクターの都合によって変更されることになって単一責任の原則には違反してしまいそうだけど、この場合はとは言えほとんど同じだからまとめても大丈夫だろうってことなんだろうか？
    - 似てるから共通化したんじゃなくて、ユースケースの段階で同じ `カタログを閲覧する` ユースケースとして定義したのかも
    - 購入者と視聴者の都合によって、 `カタログを閲覧する` 全体が影響を受けることはないってことなんじゃないかな
    - 今後、この `カタログを閲覧する` ユースケースが業務上で全く同じなら共通化してもいいんじゃない


- この本ではSRPはアクターごとに責務を分けようって話をしていて、実際にユースケースからクラスを分けたりしたのでわかりやすかった。
    - ユースケースがあってこそ、SRPができるのかな？
    - ユースケースを洗い出すのが重要そう


論理的に依存関係をきっちりしておき、手段とデプロイ境界は柔軟に変更できるようにしとけよ
という章だと読んだ


- 言語によっても「どれくらいを 1 モジュールとするか」の考え方は変わる気がする
    - 1 ファイル n クラスが書けて、クラスごとに公開範囲を決められる言語とか
    - package private がある言語とか
- ビルドツールによっても変わる
    - gradle ( jvm lang ) や sbt ( scala ) とか
    - 1 プロジェクトに n サブプロジェクトを作って、.java 間は言語の import 文で結合できる
    - 特定のサブプロジェクト間の依存を禁止したりもできる
- 1 プロジェクトでパッケージだけちゃんと分けておいて、あとで考えるってのも良いと思う
    - checkstyle ( java ) みたいな静的解析ツールで、パッケージ間の依存を禁止したりできる


- アクターごとにコンポーネント化する設計はしたことなかったかも
- P204の図と合わせて見るとコンポーネントアーキテクチャの図の理解が進みそう

# 第34章 書き残したこと



- `コンポーネントによるパッケージング 図34-6（p289）` これはコンパイラがない言語だとあんまり意味がなさそう。言語によってパッケージングも変わってくるのかな？
    - 大筋あってるけど、レビューとかでもできるけど、コンパイラで気付きたいからこの話がでているので、厳密にはコンパイラがないとできないわけではないよ
    - 頑張れば PHP でもできるかもね


- 三層レイヤーって使うことある？インターフェース使ってポートアダプターにしちゃうケースの方が多くないかな？そんなコストもかからない気がするけどどうなんだろ。

    - MVC しかやったことない人とかだと一番入りやすいかも


- 水平三層レイヤーが手っ取り早いが、問題もある
    - いずれ３つのいずれかには収まらないものが出てくる
    - なんのシステムを作っても同じになるので、アーキテクチャが叫ばない ( ｽｲﾍｲｻﾝｿｳ!!! )
- また、レイヤー設計にはルールを守ったまま実装が混在する可能性がある
    - 依存関係 `API → Service → Repository` と `API → Repository` が混じったり
    - レビューや静的解析で検知しても良いが、フィードバックループが長くなる
    - やっぱりコンパイル時に検知したい → コンポーネントによるパッケージングだ
- 悪魔は実装の詳細に宿る


- 緩いレイヤードアーキテクチャはあるある
- PHPにもpackage private ほしい
    - PHPの感覚だと実装部分（ServiceImplとか）のアクセス制御をもう少し厳しくできる、という感覚がわからんかも