[書評] Clean Architecture 達人に学ぶソフトウェアの構造と設計

# はじめに
[Clean Architecture 達人に学ぶソフトウェアの構造と設計](https://www.kadokawa.co.jp/product/301806000678/) を読んで、ソフトウェア設計について知る入り口として良かったので、どういった方にお勧めできそうか、どんなことが書かれているのか紹介します。
ソフトウェア設計初学者の方の助けになれば幸いです。

# こんな方におすすめ
クラスの単位は何?、メソッドは何をどこに書いた方が良い?など、ソフトウェア設計に初めて関わる方や、プログラミングを上達する上でソフトウェア設計を考えれるようになるきっかけが欲しい方におすすめしたいです。
この本は、クリーンアーキテクチャについてのみ書かれているわけではなく、アーキテクチャが何故重要なのかという話や、設計の原則、コンポーネントの結合・凝集性についても書かれています。ソースコードをどう書いたら良いかなど、細かい粒度では実用的な内容はあまり書かれていないので、より詳しくソフトウェア設計・実装について知りたい方は別の書籍も合わせて読むのをお勧めします。([ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本](https://www.shoeisha.co.jp/book/detail/9784798150727)、[エリック・エヴァンスのドメイン駆動設計](https://www.shoeisha.co.jp/book/detail/9784798126708)、[実践ドメイン駆動設計](https://www.shoeisha.co.jp/book/detail/9784798131610)、 など)
クリーンアーキテクチャについて知りたい方も読むと良いと思います。

# プログラミングパラダイム

## 内容
3つのプログラミングパラダイムが、何をすべきでないかを伝えていると説明されています。

- 構造化プログラミング
    - goto文をなくし、順次処理と制御構造(if文の選択、while文の反復)によって、モジュールを小さな単位に分割することができます。 → 直接的な制御はすべきでない
- オブジェクト指向プログラミング
    - 関数へのポインタの応用(ノイマン型アーキテクチャ)をなくし、ポリモーフィズムによってモジュールの依存関係を制御できます。 → 間接的な制御はすべきでない
- 関数型プログラミング
    - 関数型プログラミングでは不変の変数を使い、並行更新による問題がなくなります。 → 代入はすべきでない

## 所感
このあとの設計の原則の話は、モジュール・クラスを適切に分割し、依存関係を制御するという話なので、構造化プログラミング・オブジェクト指向プログラミングのパラダイムは大きく影響しています。
それぞれの特徴を持った言語(Python, Sacala、など)があるので、各プログラミングの特徴を知っておくのは良さそうです。

# 設計の原則
## 内容
- SRP：単一責任の原則(SRP = Single Responsibility Principle)
    - モジュールは単一のアクターに対して責務を果たします。
- OCP：オープン・クローズドの原則(OCP = Open-Closed Principle)
    - 抽象・インターフェースに対して依存関係を持たせて、変更を加える時には抽象に対する依存関係を増やすかたちにして、1方向にしか依存させないのが良いです。
- LSP：リスコフの置換原則(LSP = Liskov Substitution Principle)
    - 呼び出し元が抽象型・インターフェースに依存しているなら、抽象型を継承したクラスや、インターフェースを実装したクラスなどの派生型は置き換えが可能です。
- ISP：インターフェース分離の原則(ISP = Interface Segregation Principle)
    - 必要のない依存関係は持たせてはいけません。抽象を用意して、必要な依存関係だけ持ちましょう。
- DIP：依存関係逆転の原則(DIP = Dependency Inversion Principle)
    - 具象に依存するのではなく、抽象・インターフェースに対して依存するようにしましょう。

## 所感
これらの原則はオブジェクト指向ソフトウェア以外にも通用する原則であると説明があったが、オブジェクト指向言語で開発すると実現しやすい原則ではあると思います。オブジェクト指向言語では、モジュールの分割のしやすさ、再利用性の高さという強みがあります。

基本的に抽象・インターフェースに依存させろと言ってます。モジュールをシンプルに保つために、抽象に依存するクラスをやたらと増やすのではなく、必要最低限の依存関係にする必要があります。
ただ、この原則に従うと、結果的に管理するソースコードはどんどん増えていきそうです。なので、理解しやすい・管理しやすい単位のモジュール・クラスであることが重要だと思います。

ライブラリ・フレームワークを使った実装だと簡単に実現できることが多いと思います。(JavaだとSpring FrameworkのインターフェースによるDI、など)

# アーキテクチャ
## 内容
ソフトウェアアーキテクチャを考える上で重要なのが、境界線です。ソフトウェアの要素を分離し、お互いが分からなくなるようにします。
ユースケース、ビジネスルール、UI、データベースなど、それぞれの関心ごとに分離することで、それぞれに変更があっても独立して開発ができます。
クリーンアーキテクチャは関心事で境界線を引き、円の中心に向かうほどソフトウェアのレベルとして上位となります。また、依存性の方向は矢印の１方向のみとなります。

## 所感
クリーンアーキテクチャは、ここまで解説されていた設計の原則・コンポーネントの原則に沿って境界を引き、依存性のルールを決めたものです。
境界線を引くというのはクリーンアーキテクチャに限らず、他のアーキテクチャでもあります。クリーンアーキテクチャでなくても、境界を決めてそれの通りに実装していれば、十分に保守性の高いソフトウェアになると思います。(レイヤードアーキテクチャ、オニオンアーキテクチャ、など)

実装レベルでどうしたら良いとか、エンティティとは何か知りたいのであれば、別の本を読むと良いです。こちら[[ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本](https://www.shoeisha.co.jp/book/detail/9784798150727)]の本が分かりやすかったです。クリーンアーキテクチャのサンプルコードも載ってます。

クリーンアーキテクチャの元ネタはこの本の作者のブログにあります。なので、図についてはそちらを参照してください。
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

# 読み終えての感想・所感
初めて読んだ際には、ソフトウェア設計がよくわかっておらず、本の中で登場する原則のいくつかは、それに当てはまるような実装をしたことがなかったのと、フレームワークによって実現されていることに気づかなかったため、すぐに理解できませんでした。
業務で役立ったか考えると、プログラミングが上達することはなかったのですが、既存のソースコードが何を意図してクラス設計・実装されているか、など理解するのにこの本の知識が助けになりました。
本の内容だけでは実装に落とし込んで理解するのは難しく、ソフトウェア設計に関する別の本を読んでみたり、技術ブログを探して調べたり、などしました。この本を読んでおくと、ソフトウェア設計だけでなく、プログラミングに関する勉強にも役立ちます。

# 参考にしたもの、実装レベルで理解するために読んだ本とか
- [Clean Architecture 達人に学ぶソフトウェアの構造と設計](https://www.kadokawa.co.jp/product/301806000678/)
- [ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本](https://www.shoeisha.co.jp/book/detail/9784798150727)
- [エリック・エヴァンスのドメイン駆動設計](https://www.shoeisha.co.jp/book/detail/9784798126708)
- [実践ドメイン駆動設計](https://www.shoeisha.co.jp/book/detail/9784798131610)