Clean Architectureの個人的まとめ
はじめに
時々名前が挙がる本、Clean Architecture読みました。
定期的に内容を思い出せるようにまとめてみますが、個人的解釈なども含まれるため、正確なことを知りたい方本を買ってください。
基本的に以下の流れでまとめます
感想など
前提
アーキテクチャは問題を解決する手法をまとめているのではなく、開発や保守のコストを下げることが目的です。問題解決の方はデザインパターンと呼ばれます。
また、この本に書いてあることが全て正しいという話ではなく、その時の規模などに合わせて調整することが正しいみたいです。
第Ⅰ部 イントロダクション
1章 設計とアーキテクチャ
多少回り道になっても少しの変更に時間がかかっていることを感じたら、すでにヤバいみたいです。アーキテクチャをしっかり意識しましょう。
2章 2つの価値
謎理論にも聞こえるが、とにかくその場しのぎの実装で重要でない部分を実装するならそれよりもアーキテクチャを意識しましょうってことみたい。
もちろん「緊急で重要」が一番の優先解決事項
第Ⅱ部 構成要素から始めよ:プログラミングパラダイム
3章 パラダイム
何をすべきでないかを伝えることで生成されるコードを制御している。
一旦この話は飛ばしていいと思う
4章 構造化プログラミング
機能を分割して、テストのしやすさを上げる→いくつものテストを行うことでそのプログラムの信用性を上げることを重要としている。
かなり前から機能分割が良いとされているらしいし、テストの観点から機能分割されていることは正しいと感じる。
5章 オブジェクト指向プログラミング
OO言語にはどのような利点があり、実際Cと比べどのように違うのかが書かれています。特にポリモーフィズムがOOを支えてるみたいな雰囲気があり、依存関係の逆転によるモジュール間の疎結合が強いみたいです。
6章 関数型プログラミング
初めて聞いた考えでした。確かに代入による値の変化がないという前提があればかなりシンプルな構造にすることができそうです。もちろん全ての代入を制限は難しいですが、一部のコンポーネントにその規制を押し込むことはできそうです。
第Ⅲ部 設計の原則
SOLID原則などの説明がここから始まる。
7章 SRP 単一責任の原則
モジュール=クラスぐらいの感覚
”必ず”一つの関数が一つの機能のみ行うべきではない。の部分はケースバイケースなので意識しすぎる必要はない意味でいれました。
同じコードがある場合にまとめることは良いことの方が多いですが、たまたま同じコードを別の用途で使っている可能性があるため、修正をしない方が良い場合もあるようです。
時には複数のクラスに一つづつ関数を持たせて、それらを持つクラスが存在するといった形もあるらしい。
8章 OCP オープン。クローズドの原則
なかなか難しそうな部分にはなります。拡張することによって既存のコードが変更されない状態は理想的なクリーンアーキテクチャに一歩近づけそうです。
そのために必要なものはSRPによって処理を分割し、DIPによって依存関係をまとめることだそうです
9章 LSP リスコフの置換原則
そもそも継承を多用することは避けるべきって話は他の書籍でもよく見ます。もし使用する場合は関数をオーバーライドしてまったく異なる動きにさせないよう注意する。もし動きが変わるならその継承関係は正しくないと考えられそうです。
10章 ISP インターフェイス分離の原則
機能もりもりのインターフェイスではなく適切に分割しなさいとのことです。
11章 DIP 依存関係逆転の原則
この本でよく出てきました。
とにかく依存関係にあるものに対してインターフェイスを挟むことで具象(具体的な実装)ではなく抽象(インターフェイスで定義された関数)のみを参照することで柔軟なシステムになると言っているようです。
とはいえインターフェイスの変更もいくらでもできるのではと思ってしまいます。おそらくインターフェイスの変更はそれを実装するものに振り回されるべきではない前提の話だと思います。
”依存関係逆転”と呼ばれていますが、基本的にインターフェイスを利用した疎結合のみが利点となります。
あまり逆転感はありませんが、インターフェイスが依存する側のモジュールに存在するため、依存される側の実装が依存する側のモジュールに依存しているとして、”依存関係逆転”となるようです。名前の語源は考えない方が楽だと思います・・・。
第Ⅳ部 コンポーネントの原則
12章 コンポーネント
あまり書く内容がありませんでした。
少し低レイヤーな内容でクリーンアーキテクチャとの関わりは薄そうです。
13章 コンポーネントの凝縮性
SOLIDのような考え方がコンポーネント単位でも行われるそうです。
基本的にコンポーネントを分ける意識をしたことはないですが、REP、CCPならなんとなく実践できそうです。3つをうまく使うには経験が必要なようです。
14章 コンポーネントの結合
ADPでは循環参照をすべきでないと言っています。クラス単位でも循環参照は避けるべきと言われています。この利点として、最も末端の修正は他のクラスに影響を及ぼさないことが挙げられるようです。
SDP、SAPにおいて、依存関係をカウントすることで現在の安定度などの指標(A・I・Dなどの名前が付けられています)を算出することが可能。問題がでれば間にインターフェイスを挟むことで解決することもあるようです。
15章 アーキテクチャ
アーキテクチャの目的を再度挙げています。
方針と詳細については、目的と手段が入れ替わることのないように区別されているべきということだと思います。
16章 独立性
私は考えたことのないものでした。
選択肢を残しておくの部分については、方針が決まり実装段階に入っても依存関係の分離ができていれば別々に開発できる部分がある。進めていくうちに初期に必要だと考えていたものが不必要になることがあるため無駄を省ける。ってことのようです。(下でまた説明します)
悪い例として、最初から特定のDBに依存した開発が、途中でそのDBだと過剰であると気づいた際に別のDBに切り替えられないということだと思います(DBをよく理解しているわけではありませんが)。きちんと分離ができていればどのようなDBでも接続部分のインターフェイスの実装のみで終わるはずなのでベタベタに依存した状態も避けられ、そもそもそれが必要かどうかも後から分かることができます。それまではモックで対応可能な部分まで実装を進めるんだと思います。
17章 バウンダリー:境界線を引く
SRP的な話になります。
ビジネスルールの実装とGUIの実装はほぼ確実に分離されるべきなようです。確かにMVCパターンなどでも表示の部分とは分離することが求められますので、特に違和感はないですがコンポーネント単位でも境界を引くべきなようです。
ここの境界線は人によって認識の差が出てきそうです。
18章 境界の解剖学
モノリスは単一実行ファイルの認識。
下位レベルのサービスは上位レベルのサービスにプラグインされるとは、上位レベルからみて下位レベルがツールの一つであること(下位レベルの実装が変わっても上位レベルからは関係がない)だと思います。
システムの境界はスレッド(ローカルでにぎやか)やWebサーバー(レイテンシーが影響する)など。
19章 方針とレベル
上位レベルは下位レベルに依存すべきではない。例えば文字の出力と文字の整形をするクラスがある場合、文字の整形をするクラスは文字の出力方法を知る必要はないため、インターフェイスを使って逆転させた方が良い。
20章 ビジネスルール
なかなか独学のプログラムでビジネスルールを意識することが少ない気がします。このビジネスルールは詳細によって変化するべきものではないはずです。
21章 叫ぶアーキテクチャ
叫んでいるの感覚が分からないですが、初めてそのコードを読んだ人がどのようなプログラムであるかを分かりやすくすべきということみたい。ユースケースが分離されていればそのようになる気もする
22章 クリーンアーキテクチャ
ようやくクリーンアーキテクチャの話。
アーキテクチャの特徴の部分は基本的に今までの考えをふまえれば自然と得られるメリットに見えます。
エンティティは何かに依存すべきでないし、ユースケースはエンティティに依存してもインターフェイスアダプターには依存すべきではない。
これでユースケースと詳細な実装が区別できそうな気がします。
ここでは4層としていますが、場合によるかと思います。
23章 プレゼンターとHumbleObject
GUIなどに関してはユニットテストが難しいため、テストが容易な部分とは分離すべきとのことです。GUIを分離するのは良いとしてもそれ以外も分離するのは少し違和感がでてきそうです。ですが、この境界がアーキテクチャの境界の定義に繋がるそうです。
クラスやモジュールの責任としてテストができるものだけで構成されたものを作っておいた方が、変更後のモジュール全体の確認テストを早期に終わらせることができるという考え?
24章 部分的な境界
ここでは最初からクリーンアーキテクチャを目指してもコストが見合わない場合があるため、一時的に簡易なものを使用してもいいよみたいな話をしています。
25章 レイヤーと境界
あまりこの章での主張は分からないですが、機能の追加によってアーキテクチャの境界は変わるため定期的に確認しましょうと言いたいよう。
26章 メインコンポーネント
Mainをアプリケーションのプラグインとできると開発用や本番用などのMainを用意することができる。
わざわざMainとして章を分ける必要は分からない。
27章 サービス:あらゆる存在
特になし
28章 テスト境界
特になし
29章 クリーン組み込みアーキテクチャ
組み込みに関しては特に取り上げない
30~32章 データベース・Web。フレームワークは詳細
どれにおいても詳細である。これらが変わったからといってビジネスルールやユースケースが変わるものではない。
とはいえC++のSTLなどは分離がかなり難しいためあきらめて良い
33章 事例
特になし
34章 書き残したこと
publicを使いすぎないよう注意してという話。publicを使いすぎると意識しないうちにコンポーネント間を飛び越えた参照を持つことになりかねない。コンパイラをうまくつかって 結合しないように制御もできる。
全体を通しての感想
SOLIDの原則は意識した上で特に、依存関係間にインターフェイスを挟むことで疎結合にし、詳細を意識しないで済むことを目指すようでした。
全く設計を意識したことのない人が呼んでもかなり難しいかと思います。特に依存の流れを1方向にしようとする意識と、SOLIDの原則の理解は必要がありそうでした。
できれば各章のまとめがもう少し具体的なまとめであって欲しかったです。
また、これだけで完全にクリーンアーキテクチャを作り出すことは無理だと思います。実際の事例に当てはめてみると曖昧な部分が数多く存在すると思うので、しっかりと時間を取って今の状態を確認したり考える時間は必須なようです。
特にアーキテクチャの特徴である以下の5つは忘れないようにしたいです。
・フレームワーク非依存
・テスト可能
・UI非依存
・データベース非依存
・外部エージェント非依存
少し話はそれますが、PCのKindleだと画像が表示されないことがほとんどでした。スマホからであれば画像の確認できるので両方を確認する必要がありました。
この記事が気に入ったらサポートをしてみませんか?