【ミライトデザイン社内勉強会#30】Clean Architecture 輪読会 「第5部：アーキテクチャ③」


# 第5部

### 参考
[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/3ff45e6cf3825ed46261

# 第26章 メインコンポーネント

### Main コンポーネントは Controller みたいなイメージであっているんだろうか？
- Java の Main 文みたいなもの
- PHP の index.php みたいなもの
- Controller を呼ぶ前の一番最初にアクセスしてくれる
- Main は最下位の方針
- OS しか Main を呼び出さない
- 上位の抽象に処理を移すことが仕事


- Mainコンポーネントの役割は
    - システムの最初のエントリーポイント
    - その他のコンポーネントを作成・調整・監督する
    - FactoryやStrategyなどのグローバルな要素を作成して上位のコンポーネントに制御を渡す
- Mainコンポーネントはプラグインとして考え、設定ごとに複数のMainを持つこともできる
    - ex. 本番用・開発用・テスト用, 国別, 権限別など
        - フレームワークとかがなかったら複数の Main を持っいたりするのかも

# 第27章 サービス：あらゆる存在

- ただ処理を分離したいだけのマイクロサービスは、ただの面倒な関数呼び出しでしかない
- サービスが互いに分離していることがメリットとされるが、これは一部しか正しくない
    - マシンリソースや結合点のデータ構造において結びついていると言える
- 独立して開発保守ができることもメリットとされるが、これも一部しか正しくない
    - マイクロサービスがスケーラブルなシステムを作る唯一の方法ではない
- マイクロサービスであれば必ずしも独立デプロイができるとは限らない
- サービスの切れ目が境界ではない
    - ここを間違えるとすべてのサービスに修正を入れる必要が出てしまう 
- クラスベースの SOLID 原則と同様に、依存性の管理と拡張はサービスレベルでも検討できる


- SOA, マイクロサービスアーキテクチャの人気の理由は大きく２つ
    - サービスが互いに分離されているから
    - サービスが開発とデプロイを独立させているようにみえるから
- ただしサービスはやり取りするデータレコードと強く結びついているので、データレコードを通じて間接的に結びついている
    - ex. やり取りするデータレコードに新しいフィールドが追加されると、新フィールドを扱うすべてのサービスに影響がある
    - 間接的にサービス間の結びつきがあれば、開発・デプロイも独立できず調整が必要
- サービスアーキテクチャを構築する場合も、モノリシックなアーキテクチャのときと同様、コンポーネントの構造を持つように設計することで依存性を分離して切り替え可能なシステムを構築できるよ

# 第28章 テスト境界

- テストは具体的である
- テスト対象に常に依存している
- なのでテストは輪の最も外側である
- テストを分離しすぎてシステムと別の仕組みだと考えてはならない
- テストもいままで同様に、変化しやすいものに依存しないことを心がける
    - ここを失敗すると仕様変更で地獄を見る
- アプリケーションからテストを切り離すためにテスト用 API を作ったりすると良いぞ
    - これはシステムの構造をテストから隠すことである
    - システムの構造と密接に結合したテストは保守が大変だからだ
- 時間が経つにつれ次の様になる傾向がある
    - テストは具体的かつ個別化する
    - テスト対象は抽象的かつ一般的する
    - 違う理由違うタイミング違う方向に進化するものは、くっつけてはならない 


- テストもシステムのコンポーネントの１つ
    - テストは常にコードに対して依存している
    - Clean Architectureの図でいえば円の最も外側の扱い
- 脆弱なテスト（コード変更時に壊れやすいテスト）にならないようにテスト容易性のための設計が重要
    - テストが壊れやすいとシステムの修正に及び腰になる
    - ソフトウェア設計の第一ルールである、「変化しやすいものに依存しない」という考えはここでも適用される
        - ex. GUIに依存したテストはめっちゃ壊れやすい
- テストAPI（UI・DB・セキュリティ制約を取り除いたもの）を作成することで、アプリケーションの構造からテストの構造を切り離すことができる
    - コードは抽象かつ一般的、テストは具体的かつ個別化する傾向があるので、分離が必要
    - テストAPIは本番にデプロイされると危険なので、独立してデプロイ可能な状態にする必要がある


### テスト用の API を作成するっていうのがピンときてない。本来使われない API をテストのために作って意味あるのか？ private メソッドをテストのためにアクセスするみたいなのと同じ感じに見えるんだけど？
- テストが GUI に依存するのを避けようって話
- Unit テストの感覚が使いのかも
    - テスト用に別の入り口から実行するみたいな



# 第29章 クリーン組み込みアーキテクチャ

- ソフトウェアは長寿だが、ファームウェアやハードウェアは時代遅れになり得る
- ファームウェアとは、どこに格納されているかではなく何に依存しているかで決まる
    - プロダクトコード ( ソフトウェア ) とハードウェアとやり取りするコードのことだ
- プロダクトコードがハードウェアに依存している限りソフトウェアは長寿になれない
- 組み込みアーキテクチャでも本書の原則が適用できる
    - 関心ごとの分離、インターフェースによるプログラミング、など



- 組み込み系開発をしたことないけど、ハードウェアの進化の速度は早い＝適切に分離しないと都度作り直しになってしまうんだろう
- HAL（Hardware Abstruction Layer）、OSAL（OS Abstruction Layer）を明示的に設けているのは、そうして常に意識しないと依存の分離が難しいのかなという印象
- [https://monoist.atmarkit.co.jp/mn/articles/0704/26/news138.html](https://monoist.atmarkit.co.jp/mn/articles/0704/26/news138.html) ←これをちょっと読んだだけでも組み込み系でやることの多くがハードウェアの影響を多分に受けそうなので、思ったよりも分離は難しいんだろうな、という感じ

### SDKとかがファームウェアにあたる？

- メモリとかもっと下の階層のことがファームウェアとかじゃないかな
- SDKはファームウェアを触らなくてもいいようにしているキット
- Androidの話はファームウェアではないけど、同じだと言う意味でAndroidの話をしていると思う

### スマホアプリとかだとどうしても依存しないかな？

- OSには依存する。WebシステムであればWebサーバーに依存している。
- OSALのようなレイヤーを設けることによって、レイヤーに対して依存を緩和させる


## 次回
https://qiita.com/tkek321/items/8aba351f383f9cc052f0