これはオピニオンであり私がクリーンアーキテクチャ本にあることを正しく理解できてないかもしれませんが書いておきます。もしかしたら私のように勘違いしている人が他にもいるかも知れないし、現時点でも私がまだ勘違いしているかもしれないです。
勉強会用のスライドとして作成していたので、一部画像があります。
言いたいこと
書籍「Clean Architecture 達人に学ぶソフトウェアの構造と設計」(以下CA本)が私にはわかりづらい
- 実際に強制力のあるモジュール分割していないのであれば、それは『依存関係逆転の原則(DIP)』じゃなくて『抽象に対してプログラミング』しているだけじゃない?
- 『モジュール依存関係逆転の原則』とか『コンポーネント依存関係逆転の原則』とかそういう表現であれば自分はしっくりくる
- しっくりくるんだけど、クリーンアーキテクチャ本第5章図5-2はInteraface使ってるだけなのに『依存関係逆転』と表現している
- この図が『DIP』なのか『DIPのための単なる手法』のことなのか紛らわしい
- しっくりくるんだけど、クリーンアーキテクチャ本第5章図5-2はInteraface使ってるだけなのに『依存関係逆転』と表現している
- CA本8章にはインタフェース使ってるけどDIPじゃない例がある(後述)
最初に私の中での結論
- 『抽象に対してプログラミングせよ』
- 一般的な手法
- Swiftならプロトコル
- Javaならインタフェース
- 内部実装を知らないようにプログラミングするだけ
- 一般的な手法
- 『依存関係逆転の原則(DIP)』
- モジュールの依存関係を逆転する手法
- 一般的な手法 を利用する
- 相互依存していれば単方向の依存にもできる
- モジュールの依存関係を逆転する手法
本題
まず最初に、モジュールというものがない世界で、Swiftのプロトコルを使った例
上の図単体ではモジュールもないのでDIPとは言い切れないと思う。
これはクリーンアーキテクチャ本第5章図5-2と同じで、「ソースコードの依存関係」と「制御の方向」は逆転している。でもこれや第5章図5-2のそれはDIPなのかな?違うんじゃないのかなーという話です。
モジュールを用意して境界線をはっきりさせる
モジュールによって分割するものの、まずはプロトコルを使わずに次のように表現する
これはなんのこっちゃない、ただのモジュールA->Bの依存。
それをプロトコルをモジュールAに用意して表現すると次のようになる
プロトコルを使わずに表現した図から逆転していることがはっきりわかる。つまり、これがDIPであって単に『抽象に対してプログラミングせよ』という手法とは区別したほうがスッキリする。
繰り返しになるけども、モジュールAにプロトコルがあるのであってBにはプロトコルはない。Bにプロトコルを用意してしまうと依存関係は逆転できない。
書籍から引用
Interfaceを使ってるがDIPじゃない例
CA本の8章から引用する。
まず図8-2のControllerモジュール、Interactorモジュールに注目してほしい。
引用
FinancialReportRequesterインターフェイスは、依存関係の逆転とは別の役割を担っている。このインターフェイスの役割は、FinancialReportControllerがInteractorの内部を知りすぎないように保護することである。このインターフェイスがなければ、Controllerは推移的にFinancialEntitiesに依存してしまう。
整理すると
- FinancialReportRequesterインタフェースはInteractor側にインタフェースがある
- Controller側にない
- ControllerはInteractorに依存している(つまり逆転させていない)
- DIPしたいわけじゃなくInteractorの内部を知らないように保護しているだけ
- データのFinancialEntitiesに依存しないようにしている
- データのFinancialReportResponseには依存して良しのスタンス
- データのFinancialEntitiesに依存しないようにしている
- DIPしたいわけじゃなくInteractorの内部を知らないように保護しているだけ
- ControllerはInteractorに依存している(つまり逆転させていない)
- Controller側にない
つまりこれはインタフェースを使った一般的な手法でありDIPではない。内部を保護して知らないようにするのは『依存関係逆転の原則(DIP)』にはあたらないんじゃないかな。
使わない言葉
説明が必要なので下記の言葉を使っていません
- 安定した具象
- 何をもって安定というかはチームによる
- 上位のモジュール/下位のモジュール
- 何が上で下かっていうのは物理的なモノではないので、その説明と納得が必要