CleanArchitecture読書メモ
僕がプログラムを一番最初に書いたのは17歳の時だったが、これまでに自分が書いたソースコードを全て見直しても、おおよそ設計と呼べるものが無かった。
設計思想、設計とは何かを学ぶためにCleanArchitectureを読んだのでメモを書く。
例の図
いつも見る例のアレ。既にネットにある種々の解説を読んでみてもピンとこなかったが、本を読むとそれなりにしっくりきた気がする。自分なりにまとめてみる。
内容物
- Entities: 企業全体の最重要ビジネスルールを司る。ビジネスルールとは、例えばローンの計算など、コンピューターで行うかどうかを問わないビジネス上の重要なルールのことを指す。このビジネスルールには、例えば利子のレートや支払いスケジュールなどのデータが紐づく。このデータを最重要ビジネスデータとよぶ。この図で表現されているEntitiesは、この最重要ビジネスデータそのものと、それらにアクセス、操作する関数群で成り立っている。このEntitiesは、システムの他の要素に依存せず独立しているようにしておく必要がある。
- UseCases: 自動化されたシステムを使用する方法を記述したものであり、アプリケーション固有のビジネスルールを記述したオブジェクトである。例えばユーザーの入力やそれに対するインタラクション、入力後の処理などが相当する。ユースケースでは、エンティティに含まれる最重要ビジネスルールをいつ、どのように呼び出して使用するかを規定したルールが含まれている。ここで、ユースケースにはUIに関する記述は無いことに注意する。インターフェースを問わず、インターフェースが使用する処理が書かれている。ユースケースはアプリケーション固有である一方、エンティティはたとえアプリケーションが違ってもそのまま使用できる。そのため、ユースケースはエンティティに依存し、下位に位置する。
- Interface Adapters: この層は、エンティティやユースケースと外部を繋ぐ部分となる。図に示されているように、ControllerやGatewayがこの部分に相当する。DBやWebへの接続はこの層から行う。Interface層やUseCases層を中心に、それぞれの層をまたいだデータのやり取りが発生することになる。その場合は、常に内側の層に対して便利な構造にしておくと良い。
- Frameworks and Drivers: この層が、アプリケーションにとって最も外側の層となる。DBやUIが相当する。肝要なのは、これらは円の内側に依存するが、円の内側であるEntitiesやUseCasesはこれらに依存しないことだ。
依存方向のコントロールとコンポーネント粒度
この本では、依存方向のコントロールと適切なコンポーネント粒度の重要性について語り口を変えて幾度も説かれている。アプリケーションやソースコードに依存が発生するのは避けられないが、依存の方向はコントロールすることが出来る。それが出来れば、依存先に重大な変更が加わった場合でも、依存している側への影響は最小限で済む。そのために、例えば必ずインターフェースを定義、用意しておくことでコントロールが容易になるなどの例が繰り返し紹介されている。
また、依存方向をコントロールするためには、適切なコンポーネント粒度である必要がある。コンポーネントが密結合すぎると、アーキテクチャの変更等アプリケーションにとって大きな変更が加わった場合に対応できなくなる。コンポーネントの分割粒度や可変/普遍など詳しくは書籍の中で触れられているが、それぞれのコンポーネントがどういう位置づけで、他のコンポーネントとどのように関わるのかは常に意識したい。
個人的には、こういったことを意識することでテスタブルなコードを書けることも嬉しい。
まとめ
本書を読むまで、上記の図すら理解出来なかったがまずはそこをクリア出来てよかった。クリアするためにはその前提である依存方向のコントロールやコンポーネント粒度を理解しておかねばならず、その理解が無かった僕にとっては多くの収穫があった。本の中でも触れられているが、あくまで円の図は一例であるので、実際のアーキテクチャを考えるにあたっては完成はなく常に見直し続けることが大事らしい。そういった考えに至れたり、少しずつ自分の書くコードがまともになっている気がするのはほんの少し進歩したと思う。思いたい。