「Clean Architecture」を読んだので、その要点

[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)

<img src="https://images-na.ssl-images-amazon.com/images/I/51LkcwTMC8L._SX387_BO1,204,203,200_.jpg" width=30% />

です。すでにたくさん記事のあるお話なので、まず参考記事から。

https://qiita.com/nrslib/items/a5f902c4defc83bd46b8

https://qiita.com/yoshinori_hisakawa/items/25576a62123607a696f6

[実践クリーンアーキテクチャ │ nrslib](https://nrslib.com/clean-architecture/)
この図が有名: [クリーンアーキテクチャ完全に理解した](https://gist.github.com/mpppk/609d592f25cab9312654b39f1b357c60)
![](https://camo.githubusercontent.com/03ac594e22a7b1c71c177e4cf8ea727319f4f9762a19e6a932deb280384296f6/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f32383436342f31316431383638392d396139392d356263302d333964632d6534383632336631643131632e6a706567)


## 要点

- アーキテクチャは、システムを形作る重要な設計決定を表したものである。ここでの重要性は、変更コストによって計測できる。
- 優れたアーキテクチャのコストが高いと思うなら、劣ったアーキテクチャにすればいい。 
- アーキテクチャはプロジェクトの初期段階に決定したいと思うものだが、必ずしも他より適切なものになるとは限らない。 
- アーキテクチャは、実装と計測によって証明すべき仮説である。
- アーキテクチャのルールはどれも同じである！ 
- 設計とアーキテクチャについては、何年も混乱が生じている。設計とは何か？　アーキテクチャとは何か？　両者の違いは何か？
    - まずは、両者に違いがないことから主張したい。何も違いはないのだ。
- ソフトウェアアーキテクチャの目的は、求められるシステムを構築・保守するために必要な人材を最小限に抑えることである。
- 機能？それともアーキテクチャ？価値が大きいのはどちらだろうか？ソフトウェアシステムが動作することが重要だろうか？簡単に変更できることのほうが重要なのだろうか？
    - ビジネスマネージャーに質問すると、ソフトウェアシステムが動作することが重要であると答える。開発者もこの意見に賛同することが多い。だが、これは間違った態度だ。
- 緊急と重要の2種類の問題がある。緊急と重要は違う。重要なことが緊急になるわけではない
    - ビジネスマネージャーや開発者がよくやる間違いは、3の項目を1に昇格させることだ。つまり、「緊急だが重要ではない」ものと「緊急かつ重要」なものを区別できていないのである。こうした間違いは、システムの重要ではないことを優先して、システムの重要なアーキテクチャを無視することにつながる。
    - アイゼンハワーのマトリクス
    - [案件や改善項目の優先順位の決め方 - Qiita](https://qiita.com/kenji-yokoi/items/3ad597100a9366f088c3)
- マネジメントチームも、マーケティングチームも、セールスチームも、オペレーションチームも常に闘争である。
    - 優れたソフトウェア開発チームは、真正面から闘争に立ち向かう。
- アーキテクチャを後回しにすると、システムの開発コストはますます高くなり、システムの一部または全部が変更不能になる
- これらの3つが、アーキテクチャの3つの大きな関心事に対応していることに注目してほしい。その3つとは「コンポーネントの分離」「データ管理」「機能」である
- 構造化プログラミングは、直接的な制御の移行に規律を課すものである。
- オブジェクト指向プログラミングは、間接的な制御の移行に規律を課すものである。
- 関数型プログラミングは、代入に規律を課すものである。
- それぞれがコードの書き方に何らかの制限をかけている。
- SOLID原則の目的は、中間レベルのソフトウェア構造を作ることだ。
- 変更に強いこと
- 理解しやすいこと
- コンポーネントの基盤として、多くのソフトウェアシステムで利用できること
- 「中間レベルの」とは、SOLID原則がモジュールレベルの開発に使われるものであることを意図している。
- 単一責任の原則（SRP：Single Responsibility Principle）
- コンウェイの法則から導かれる当然の帰結。個々のモジュールを変更する理由がたったひとつだけになるように、ソフトウェアシステムの構造がそれを使う組織の社会的構造に大きな影響を受けるようにする。
- リスコフの置換原則（LSP：Liskov Substitution Principle）
- Barbara Liskovが提唱した有名な派生型の定義。1988年に誕生。要するに、交換可能なパーツを使ってソフトウェアシステムを構築するなら、個々のパーツが交換可能となるような契約に従わなければいけない
- インターフェイス分離の原則（ISP：Interface Segregation Principle）
- ソフトウェアを設計する際には、使っていないものへの依存を回避すべきだという原則。
- 依存関係逆転の原則（DIP：Dependency Inversion Principle
- コンポーネントAがコンポーネントBの変更から保護されるべきならば、BからAへ依存すべき。
- Presenterを変更したときに、Controllerを変更する必要をなくしたい。Viewsを変更したときに、Presenterを変更する必要をなくしたい。他のすべてを変更したときに、Interactorを変更する必要をなくしたい。
- なぜInteractorがそんなにも特権的な位置づけになるのだろう？それは、ビジネスルールを含んでいるからだ。Interactorは、アプリケーションの最上位レベルの方針を含んでいる。そのほかのコンポーネントは、周辺にある関心事を処理している。Interactorは、その中心となる関心事を処理している。
- これがアーキテクチャレベルにおけるオープン・クローズドの原則（OCP）だ。アーキテクトはいつどのような理由でどのように変更するかを考えて機能を分割する。分割した機能をコンポーネントの階層構造にまとめる。上位レベルにあるコンポーネントは、下位が変更されたとしても、変更する必要はない。
- オブジェクト指向の黎明期には、リスコフの置換原則（LSP）は（先ほどのセクションで紹介したような）継承の使い方の指針になるものだと考えられていた。だが、時間をかけてその適用範囲は広がり、今ではインターフェイスと実装に関するソフトウェア設計の原則になっている。
- Acmeというタクシー会社が、仕様をきちんと読み取れないプログラマを雇ったとしよう。そのプログラマは、destinationというフィールド名をdestと省略してしまった。Acmeは地域最大のタクシー会社で、CEOの離婚した元妻が我々の会社のCEOと結婚するらしい……。さて、なんとなく状況はわかった
    - 有能なアーキテクトなら小細工は許さないだろう。"acme"をハードコーディングしてしまうと、ありとあらゆる不具合の原因になってしまう。
    - 成長を続けるAcmeが別のタクシー会社Purpleを買収したとしよう。合併した新会社のなかで、AcmeとPurpleはそれぞれ別々のブランドとして生き続けることになった。
- リスコフの置換原則（LSP）違反のお手本のような例が、かの有名な（悪名高いと言うべきか）正方形・長方形問題
- 閉鎖性共通の原則（CCP）
- 同じ理由、同じタイミングで変更されるクラスをコンポーネントにまとめること。変更の理由やタイミングが異なるクラスは、別のコンポーネントに分けること。
- これは、単一責任の原則（SRP）をコンポーネント向けに言い換えたものだ
- コンポーネントのユーザーに対して、実際には使わないものへの依存を強要してはいけない。
- 全再利用の原則（CRP）も、ひとつのコンポーネントにまとめるべきクラスやモジュールを判断するための原則である。一緒に用いられることが多いクラスやモジュールは同じコンポーネントにまとめよというもの
- アーキテクチャの形状の目的は、そこに含まれるソフトウェアシステムの開発・デプロイ・運用・保守を容易にすることである。
- それらを容易にするための戦略は、できるだけ長い期間、できるだけ多く選択肢を残すことである。
- 開発が難しいソフトウェアシステムは、ライフタイムが長くて健全である可能性が低い。だからこそ、システムのアーキテクチャによって、開発チームが開発しやすくなるようなシステムにするべきなのである。
- チームの構成が異なれば、アーキテクチャの決定も異なる。
- アーキテクチャを慎重に考え抜けばコストは大幅に低下する。システムをコンポーネントに分離して、安定したインターフェイスを持つ独立したコンポーネントにしておけば、将来の機能の道筋が照らされ、意図せずに壊してしまうリスクを大幅に軽減できるだろう。
- 優れたアーキテクチャは以下のことをサポートしなければいけない。
    - システムのユースケース
    - システムの運用
    - システムの開発
    - システムのデプロイ
- アーキテクチャは、開発環境のサポートにおいて、非常に重要な役割を果たす。ここで、コンウェイの法則が作用する。
- コンウェイの法則: システムを設計する組織は、組織のコミュニケーション構造をコピーした構造の設計を生み出す。
- 方針の議論には、単一責任の原則（SRP）、オープン・クローズドの原則（OCP）、閉鎖性共通の原則（CCP）、依存関係逆転の原則（DIP）、安定依存の原則（SDP）、安定度・抽象度等価の原則（SAP）が混在している。それぞれの原則がどこで使われているのか、どうして使われているのかを確認する
- アーキテクチャの観点では、データベースはエンティティではない。データベースは詳細であり、アーキテクチャの構成要素として現れることはない。ソフトウェアシステムのアーキテクチャにおけるデータベースの立ち位置は、あなたが住む家におけるドアノブのようなものだ。
- GUIは詳細である。ウェブはGUIである。したがって、ウェブは詳細である。アーキテクトとしては、こうした詳細をビジネスロジックの中心から切り離しておきたい。
    - こんなふうに考えてみよう。ウェブは入出力デバイスの一種である。我々は、デバイスに依存しないアプリケーションを書くことを学んだ。


## まとめ

既に多方面で読まれている教科書的な本。
なので、読むことで皆で会話がしやすくなることに役立つ。そんな読書録でした。

以上です～