書籍「Clean Architecture 達人に学ぶソフトウェアの構造と設計」を読んだので大事なポイントを自分のためにまとめてみた


## はじめに
[Clean Architecture 達人に学ぶソフトウェアの構造と設計](https://www.amazon.co.jp/dp/4048930656)を読んだ。
なぜソースコードを綺麗に書くのかから始まり、オブジェクト指向、コンポーネントの原則、アーキテクチャと体系的にまとまっている良い内容だった。
この記事では、本書の内容の引用を踏まえながら自分の考えの振り返りをまとめたものである。

実際にGoで実装したりしたので、なにか間違いなどあれば指摘していただきたい。
[クリーンアーキテクチャの書籍を読んだのでAPIサーバを実装してみた](https://qiita.com/yoshinori_hisakawa/items/f934178d4bd476c8da32)

## 対象読者
・Clean Architecture 達人に学ぶソフトウェアの構造と設計を読むか迷ってる人
・Clean Architecture について興味がある人
・実際にソースコードを見てClean Architectureを理解したい人

## Clean Architectureの内容
### 本書の導入
> 早く進む唯一の方法は、うまく進むことである。

時間がないとソースコードの汚い部分は後で対応するといって一度マージされる。
結果として誰も直さずにそのソースコードは汚い道を歩き続ける。保守が大変になる。
結果として早く進む一番の方法は、クリーンなコードを書き続けることである。

そして、ソフトウェア開発者にしか、アーキテクチャの事はわからない。
外部の人間が何と言おうと、我々ソフトウェア開発者はアーキテクチャと真正面から向き合う必要がある。

### 設計の原則
> SOLIDの原則の目的は、「変更に強く、理解しやすく、多くのシステムで再利用できる」ソフトウェア構造を作ることである。

以下がSOLIDの原則のまとめ

- S - 単一責任の原則(SRP:Single Responsibility Principle)
　- モジュールを変更する理由は１つでなければならない
- O - オープン・クローズドの原則 (OCP:Open-Closed Principle)
    - モジュールは拡張に対して開き、修正に対して閉じていなければならない
- L - リスコフ置換原則 (LSP:Liskov Substitution Principle)
    - 派生型はその基本型と置換可能でなければならない
- I - インターフェース分離の原則 (ISP:Interface Segregation Principle)
    - クライアントが利用しないメソッドへの依存を強制してはならない
- D - 依存性逆転の原則（DIP:Dependency Inversion Principle）
    - 「抽象」は実装の詳細に依存してはならない、実装の詳細が「抽象」に依存すべきである

詳しくはこちらの記事にまとめたので一読してほしい。
[【ボブおじさんのClean Architectureまとめ】オブジェクト指向 ~SOLIDの原則~](https://qiita.com/yoshinori_hisakawa/items/25576a62123607a696f6)

### コンポーネントの原則　～コンポーネントの凝集性～
> コンポーネント（デプロイの単位のこと）の凝集性を高めるには、
> 「不要なものに依存しないこと」「同じタイミング、同じ理由で変更されるものはひとまとめにすること」が重要である。

- 全再利用の原則（CRP:Common Reuse Principle）
    - コンポーネントのユーザに対して、実際には使わないものへの依存を強要してはいけない

- 閉鎖性共通の原則（CCP:Common Closure Principle）
    - 同じ理由、同じタイミングで変更されるクラスをコンポーネントにまとめる
    - 変更の理由やタイミングが異なるクラスは、別のコンポーネントに分ける

- 再利用・リリース等価の原則（REP:Reuse-Release Equivalency Principle）
    - 再利用の単位とリリースの単位は等価になる

### コンポーネントの原則　～コンポーネントの結合～
> コンポーネントを疎結合にするには、「循環依存を作らないこと」「抽象度が高くなる方向に依存すること」が重要である。

- 非循環依存関係の原則（ADP:Acyclic Dependencies Principle）
    - コンポーネントの依存グラフに循環依存があってはならない

- 安定依存の原則（SDP:Stable Dependencies Principle）
    - 安定度の高い方向に依存する

- 安定度・抽象度等価の原則（SAP:Stable Absstractions Principle）
    - コンポーネントの抽象度は、その安定度と同程度でなければいけない


### アーキテクチャ
#### アーキテクチャとは
> ソフトウェアシステムは、「方針」と「詳細」に分割できる。方針は、ビジネスのすべてのルールや手順を含んでいる。方針には、システムの本当の価値がある。
> 「方針」と「詳細」は慎重に区別して、「方針」が「詳細」に決して依存することがないように切り離す。
> 詳細には、IOデバイス・データベース・ウェブシステム・サーバ・フレームワーク・通信プロトコルなどが含まれる。
> 詳細の決定を延期や留保できれば、実験できる数が増え、挑戦できることが増え、決定しなければいけない時点までに入手できる情報が増える。

実際にClean Architectureに書かれている内容を参考にAPIサーバを実装してみた。
言葉だけでなく実際にソースコードとして形にすることが何よりも重要である。
[クリーンアーキテクチャの書籍を読んだのでAPIサーバを実装してみた](https://qiita.com/yoshinori_hisakawa/items/f934178d4bd476c8da32)

#### 重複
> ソフトウェア開発の世界では、「重複は悪」とされる。しかし、明らかに重複していたコードが、
> 変更理由が異なるために個別に進化を遂げ、数年後には両者がまるで違ったものになっていることがある。これは「本物の重複」ではない。

重複を避けるために抽象クラスを作る事があると思う。
注意しなければいけないことは、その二つは「本物の重複」かどうかを見極める事である。
仮に「嘘の重複」だった場合、徐々にソースコードは汚くなっていく。


#### 境界線を引く
> アーキテクチャとは、境界線を引く技芸である。ソフトウェアの要素を分離し、お互いのことがわからないように制限する。
> 境界線は「重要なもの」と「重要ではないもの」の間に引く。境界線を挟んだコンポーネントは、それぞれ変更の頻度や理由が違っている。

例えば最初からMySQLを使うことを決める必要はあるか？
もしかしたらファイルに出力する形式事足りるかもしれない。
なのでこの決定は「重要ではないもの」に分類される。
そういった「重要ではないもの」に振り回されないためにも境界線を引き、「重要なもの」から手を付ける必要がある。

#### 叫ぶアーキテクチャ
> あなたのアプリケーションのアーキテクチャはなんと叫んでいるだろうか？
> 最上位レベルのディレクトリ構造と最上位レベルのパッケージのソースファイルは、「ヘルスケアシステム」「会計システム」「在庫管理システム」と叫んでいるだろうか？
> それとも「Rails」「Spring/Hibernate」「ASP」と叫んでいるだろうか？

Domainレイヤーにフレームワークや外部の詳細が入り込んできてはいけない。
入り込んでくると、他のフレームワークに変えることが難しくなる。ドメインレイヤーに影響が及ぶ。
徐々にDomainレイヤーに不要な者たちが入り込んでくるので、常に注意を払う必要がある。

## まとめ
Clean Architectureの書籍の中で、印象に残った箇所や自分の考えをまとめてみた。
実際にコーディングするのはすごく大変だった。

書籍やソースコードを通して自分の頭の中がDirtyな状態からとてもCleanな状態になったと感じている。