#はじめに
ドメイン駆動設計(DDD)のアーキテクチャについて調べていたところ「DIP」という謎の略語を見つけたので整理してみました。
#レイヤー化アーキテクチャ
昔からあるアーキテクチャの一つ。基本的な思想は以下の通り。
- レイヤごとに関心事を分離する
- 上位のレイヤは下位のレイヤにのみ依存する
レイヤごとに関心事を分離することで各レイヤの開発が容易になります。例えば、ユーザーインターフェース層を担当する開発者は何のデータベースを使うかというインフラストラクチャ層の関心事を意識せずに開発を進めることができます。
##各レイヤの役割
####ユーザーインターフェース層
ユーザーへの画面表示やユーザーによるアプリケーションへの操作を担当します。
例:ブラウザへの表示、入力フォームからの登録
####アプリケーション層
システムで実現するユースケースを担当します。
例:ユーザーの入力値をもとにデータを参照・登録・更新・削除する手続きを提供
####ドメイン層
ドメインのルールに基づいてデータを加工・計算・判断します。
例:値オブジェクトによるドメインのルールの定義、アプリケーション層への手続きの提供
####インフラストラクチャ層
データの永続化や外部システムとの連携部分を担当します。
「上位のレイヤは下位のレイヤにのみ依存する」という原則にもとづくと、ある意味ではインフラストラクチャ層の変更が上位のレイヤに影響を与えてしまうことになります。例えば、OracleからPostgreSQLへ移行するとなるとアプリケーション層やドメイン層が影響を受けてしまうのです。
#DIP(Dependency Inversion Principle) - 依存関係逆転の原則
とりあえず図を見てみましょう。
ついでに、従来のレイヤー化アーキテクチャと横並びで見てみましょう。
これまで最下層に存在していたインフラストラクチャ層が最上位に移動しています。これによって、永続化の変更や外部システムへの連携(データの取得・送信)の仕様が変更となっても下位のレイヤは何の影響を受けません(というよりはむしろ、影響を受けないように実装しなければなりません)。
##DIPの定義
上位のモジュールは下位のモジュールに依存してはならない。どちらのモジュールも、抽象に依存すべきである。
抽象は、実装の詳細に依存すべきではない。実装の詳細が、抽象に依存すべきである。
実践ドメイン駆動設計 p.118
##「抽象に依存する」とは何か
具体的には、ドメイン層で定義したインターフェースに依存することです。インターフェースは、具体的な実装ではなく手続きの仕様を提供するため、その意味で「抽象」の役割を担うことになります。
例えば、ProductRepositoryというインターフェースに基づき、ProductMySQLRepositoryImplやProductOracleRepositoryImplを実装することで機能を実現します。抽象への依存を実現する手段としてはDI(Dependency Injection)などがあります。
#参考資料
実践ドメイン駆動設計