152
Help us understand the problem. What are the problem?

posted at

updated at

図解クリーンアーキテクチャ

こちらに詳細に記載しています。宜しければご参照ください。

概要

一見複雑に見えるクリーンアーキテクチャをSOLID原則を用いて、成り立ちをひも解いていきます。

背景

クリーンアーキテクチャを調べていくと下記のような概念図や構成図を見かけます。
image.png
image (1).png

言いたいことは何となく分かるのですが、初見でメリットが理解できませんでした。
本記事ではレイヤードアーキテクチャの欠点を
SOLID原則に沿って補完していくことで、クリーンアーキテクチャをひも解いていきたいと思います。

SOLID原則とは

ソフトウェアの拡張性、保守性等を担保し、メンテナンスしにくいプログラムになることを防ぐための原則です。

S:SRP、単一責任の原則
O:OCP、開放閉鎖の原則
L:LSP、リスコフの置換原則
I:ISP、インタフェース分離の原則
D:DIP、依存性逆転の原則
SOLID原則の詳細はこちらの記事が参考になります。
イラストで理解するSOLID原則

クリーンアーキテクチャが必要な理由

layer.png

こちらの最も基本的なレイヤードアーキテクチャの欠点からクリーンアーキテクチャの必要性を見ていきます。

依存性逆転の原則 (DIP: Dependency Inversion Principle) その①

上図のレイヤードアーキテクチャの欠点の一つにDomain層が、Infrastructure層に依存していることが挙げられます。

安定依存の原則(SDP:The Stable Dependencies Principle)によれば
安定しているDomain層が、変更が多く不安定なInfrastructure層に依存していることは安定依存の原則に反しています。
infra.png

この依存関係を解決する考え方として依存性逆転の原則があります。
依存性逆転の原則に従うとDomainとInfrastructureの関係は下記のようになります。

infra逆転.png

DomainとInfrastructureの間にInterfaceを設けます。
この構成によりDomainからInfrastructureを抽象化します

依存性逆転の原則 (DIP: Dependency Inversion Principle) その②

依存性逆転の原則により、DomainとInfrastructureの関係を逆転させました。
しかし、まだ完全には依存関係を切り離せていません。

下記の実装を見て見ます

domain.java
DataAccessInterface interface = new Infrastructure();
interface.getData();

実装を考えるとDomainが、Data Access Interfaceを呼び出すときにInfrastructureをインスタンス化する必要があります。

そこでDomainからInfrastructureのインスタンスを隠蔽するため、
Infrastructureをインスタンス化するData Accessを配置することでこの問題を解決します。

bbb.png

domain.java
DataAccessInterface interface = new DataAccess();
interface.getData();
DataAccess.java
@Override
public void int getData(){
    Infrastructure infra = new Infrastructure();
    infra.getDataFromInfra();
}

この構成によってDamainからInfrastructureを抽象化します

DataAccessのようなデータアクセス手段、データの永続化を抽象化するオブジェクトをRepositoryと呼びます。デザインパターンのリポジトリパターンとして知られています。

開放閉鎖の原則 (OCP:Open/Closed Principle)

次に視点を変えてUI(Presentation)とApplicationの依存関係に目を向けてみます。
bbb.png

一般的に、UIはユーザーの目に最も触れるため比較的変更が多く発生します。
このため、UIの変更をApplicationに波及させたくなく、
また、Applicationの変更にUIも振り回されたくありません。

こうした事態を解決する考え方として開放閉鎖の原則の考え方があります。

拡張に対して開いていなければならず、 修正に対して閉じていなければならない。という
開放閉鎖の原則に基づきApplication Interfaceを設けます。
合わせて"依存性逆転の原則 (DIP: Dependency Inversion Principle) その②"と同様にインスタンス化のControllerを設けます。
aaa.png

この構成により、変更の多いUI(Presentation)は拡張に対して開いており、修正に対して閉じている状態に変更されます。

単一責任の原則 (SRP:Single Responsibility Principle) その①

今度は依存関係ではなく、各モジュールの責務に目を向けてみます。

aaa.png
上図Domainの責務は2つ存在しています。


1.ユースケースの実行

Applicationの要求に基づき、Data Access Interfaceからデータ取得

2.ビジネスロジックの実行

Data Access Interfaceからのデータを加工する等ビジネスロジック実行

このためDomainは、2つの変更理由によって修正が加えられます。
この問題として、一方の修正によってもう一方のコードに予期せぬ影響を及ぼすかもしれません。

こうした問題への考え方として単一責任の原則があります。
この考え方によると一つのモジュールは二つ以上の変更理由で変更されてはなりません。

この考えに基づいて、Domainを分割します。
ビジネスルールを提供するモジュールをEntitiesと、
Data Access Interfaceを介してデータを取得するモジュールをUseCase Interactorとします。
aaa (1).png

単一責任の原則 (SRP:Single Responsibility Principle) その②

次にUI(Presentation)について考えます。

UI(Presentation)も責務が2つ存在します。


1.Viewからのイベント通知

UI(Presentation)からのUIイベントをControllerに通知

2.Viewへのデータ解釈

ControllerからのデータをUI(Presentation)に渡す

"単一責任の原則 (SRP:Single Responsibility Principle) その①"と同じ考え方に基づき分割します。
Viewへのデータ解釈を担うモジュールをPresenterとして分割します
presenter_split.png

インターフェース分離の原則(ISP:Interface Segregation Principle)

先ほど分割したControllerとPresenterについて考えます。

Controllerの責務はViewの状態を受け取ってApplication Interfaceを介して、
Applicationが要求するデータ形式でデータを引き渡すことです。

一方でPresenterの責務は、Controllerを介してApplicationのデータを受け取ることです。

このとき一つの問題が生じます。
Controllerに本来責務でない実装が入ってしまいます。
Application InterfaceのリターンをPresentationに渡す実装が必要となります。

こうした問題を解決する考え方にインターフェース分離の原則があります。
presenter_interface.png

Controllerは
責務に沿ったInterfaceのみを呼び出せるようにInput Boundaryを配置されました。

Presenterも
責務に沿ったInterfaceのみを実装できるように、Output Boundaryを配置されます。

この構成にシステム境界線を引いてみます。
system_config.png

この図をクリーンアーキテクチャの構成図と見比べてみます。
cleanarch_config.png

ほとんどの構成が同じではないでしょうか?
こうして見て見るとクリーンアーキテクチャの構成がなぜこのような構成が理由をもって理解できるのではないでしょうか?

さいごに

クリーンアーキテクチャをSOLID原則の観点で見ていきました。

いきなりクリーンアーキテクチャだけを見てしまうと難解に思えてしまいますが、
順を追ってみていくと既存の考え方の組み合わせのように見えます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
152
Help us understand the problem. What are the problem?