おおざっぱなクリーンアーキテクチャ理解

# 概要
- ものすごい大ざっぱな人がクリーンアーキテクチャ勉強したのでその記録
- 本読んだだけなので間違ってたら指摘ください
- 本には書いてない自分の感想（そのように解釈したのも含む）は、章節項の頭に「（感想）」と書く
- （感想）読書のモチベーション
    - 昔からデスクトップアプリの開発が苦手
    - 今はC#でもPrismとかあって非常に良い
    - それでもしんどいのでこれさえ守っておけばオッケー的な定石を知りたい

# （感想）自分の今の結論
- ![勘違いしやすい図](https://i.imgur.com/soH76BV.jpg)
- 超要約
    - レイヤアプローチ
    - 外側は直近の内側にのみ依存する
    - 依存関係が逆にならないように「依存関係逆転の法則」を用いる
    - 内側、外側に入る固有名詞は重要ではない（システムで違う）
    - 何が内側で何が外側かを見極めるのは実は難しい
- クリーンアーキテクチャとはメタアーキテクチャである
- メタアーキテクチャはすべてのソフトウェアで同じである
- クリーンアーキテクチャとは依存関係の話である

# （感想）なぜ自分がメタアーキテクチャと呼んでいるのか
- ユースケースが内側にくるのが一般的だが、何が内側で何が外側でも問題ない
- 一般的なアーキテクチャは構造について言及している
- クリーンアーキテクチャは構造のルールについて言及している
- 良いアーキテクチャの構造を示すための定理が「原則（ルール）」

# （感想）書籍は以下について書かれている
- モジュール
    - オブジェクト指向の原則
- コンポーネント
    - コンポーネントの原則
- アーキテクチャ
- 境界
    - バウンダリとも呼ぶ。どこでレイヤを分けるか？
- クリーンアーキテクチャ（自分の言うメタアーキテクチャ）
- クリーンアーキテクチャにおける設計の勘所と俗説の嘘（書籍の1/3）
- ソフトウェアの歴史（書籍の1/4）
- 読むのが大変なのはコンポーネントのところまで（がんばろう）

# 内容

## 前ふり
- ソフトウェアアーキテクチャの真理
    - 「アーキテクチャの【ルール】はすべて同じである！」

## モジュール
- （感想）よく知られているので「依存関係逆転の法則」だけおさらい
- オブジェクト指向の原則
    - 単一責任の原則
    - 開放閉鎖原則（Open-Closed Principle）
    - リスコフの置換法則
    - インターフェイス分離の法則
    - 依存関係逆転の法則
- 依存関係逆転の法則
    - ![依存関係逆転の法則](https://i.imgur.com/vrdhy7m.png)
    - レイヤの境界をまたがる矢印の向きが逆なのに注目

## コンポーネント
- （感想）コンポーネントの善し悪しの議論はされないことが案外多い
- コンポーネントの原則
    - よく知られていないので要理解
        - 再利用リリース等価の原則（REP）
        - 閉鎖性共通の原則（CCP）
        - 全利用の原則（CRP）
    - 三すくみでトレードオフになっている
        - ![テンション図](https://i.imgur.com/yJLvPnE.png)
- コンポーネント図の使い方
    - （感想）クリーンアーキテクチャでは重要な図
    - コンポーネント間の依存に問題がないか
    - 循環依存の検出
    - 循環依存があるとビルドできねえよ
        - （感想）某社で.NETのシステムで問題になっているのを聞いた
- 安定依存の法則
    - 依存するなら安定した方に依存
    - 外側から内側に依存するのがクリーンアーキテクチャなら内側が安定してないとダメ
- 安定度・抽象度等価の原則
    - 抽象度が高いほど安定度が上がる
    - 安定度の高い内側を改変する場合は「開放閉鎖原則」を使う
- 安定度と抽象度のマトリクス
    - ![主系列](https://i.imgur.com/MblxTZq.png)
    - 物事には程度がある
    - 抽象度が低く安定度が低すぎるとしんどい
    - 安定度が高く抽象度が高すぎると無駄

## アーキテクチャ
- 方針と詳細
    - 方針＝アーキテクチャ、アーキテクチャは安定度の高い抽象レイヤに存在する
    - 詳細＝実装、実装は安定度の低い具象レイヤに存在する
    - フレームワークのような詳細の決定は遅延させる
- 独立性
    - アーキテクチャがユースケースの意図を表現する
        - ショッピングカートのアーキテクチャはショッピングカートに見える
    - アーキテクチャはシステムの振る舞いに影響しない

## 境界
- （感想）何が内側で何が外側かという判断の難しい話につながる
- いつ何に境界線を引くか？
    - UIはビジネスルールにとって重要ではない（外側の存在）
    - データベースも外側
    - ビジネスルールは内側なので切り離す
    - フレームワーク、ライブラリは外側なので後で決める
    - 境界線は変更の軸のあるところに置く
- データの受け渡し
    - インターフェイス、データの定義は呼び出される側（つまり内側）にある

## （まとめ）クリーンアーキテクチャ全体像
### 全体像
- ![勘違いしやすい図](https://i.imgur.com/soH76BV.jpg)
- レイヤアプローチ
    - 外側は直近の内側にのみ依存する
    - 依存関係が逆にならないように「依存関係逆転の法則」を用いる
- 安定度と抽象化の話
    - 抽象度が高いほど安定度が上がる
    - 内側ほど抽象度が高いことになる
- 境界の話
    - 標準的なレイヤの「あくまで例」
    - UIとかWeb、RDBMS、デバイスはIOなので外側
    - IOを抽象化、制御するレイヤがその内側
    - ビジネスルールを制御するのがユースケースでその内側
    - ビジネスルールをエンティティと呼び、最も内側

### （感想）ちなみに
- 組み込み開発でも適用可能なアーキテクチャ
- MVVMがクリーンアーキテクチャである例示
    - ![MVVM](https://i.imgur.com/rzVJy0l.png)
    - クリーンアーキテクチャの例の図を参照
    - ビューが一番外の青い部分
    - ビューモデルとモデルが緑の部分（密結合が許される）
    - サービスが赤い部分
    - サービスから呼ぶビジネスロジックが黄色の部分
    - モデルのうちRDBMSアクセスはORM（またはDAO）を介して青い部分に戻る
    - 依存関係と抽象度、安定度を確認すること
    - MVVMはクリーンアーキテクチャに含むことができる
    - つまりMVVMとクリーンアーキテクチャはアーキテクチャのメタ度のレベルが違う
- BCE、3階層アーキテクチャとの違い
    - BCE
        - ![BCE](https://i.imgur.com/KwTcTal.png)
        - メロンを左に倒した図形が「バウンダリ（B）」
        - 再読み込みボタンみたいな図形が「コントロール（C）」
        - 丸の下に棒がある図形が「エンティティ（E）」
    - 3階層アーキテクチャ
        - ![3階層アーキテクチャ](https://i.imgur.com/ym8g2wX.png)
        - 非常に見慣れているので詳細割愛
    - これらはレイヤアプローチだが、依存の方向の考え方が違う
    - これらだとUI（BCEで言うバウンダリor3階層のプレゼンテーション層）が最上位になる
    - 依存性の観点がないと古い人にはクリーンアーキテクチャは直感に反す
    - 書籍の中ではBCEはクリーンアーキテクチャに含まれると言及
    - 書籍の中では3階層はアーキテクチャでなくトポロジだと言及