[ドメイン駆動設計] オニオンアーキテクチャでのフォルダ構造
#目的
DDDはドメイン層がコアとなるので、オニオンアーキテクチャ等のドメイン層を中心に持つアーキテクチャがイメージしやすい。そして、このアーキテクチャを考慮したフォルダ構成を適用することで、このアーキテクチャを反映した実装も行いやすい。そこで、この記事ではフォルダ構造を提案する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415097/e459cf6c-66f8-b72b-630d-8c49fd3c8b2c.png" width="450">
#フォルダ構造
┳ app ┳ presentation ━━┳ REST API
┃ ┃ ┗ SUB
┃ ┠ infrastructure ┳ repository(実装: domain.repository)
┃ ┃ ┗ PUB (実装: application.PUB)
┃ ┠ application ━━ ┳ usecase1
┃ ┃ ┠ usecase2
┃ ┃ ┗ PUB(インターフェース)
┃ ┗ domain ━━━━━━━━┳ models ┳ root-entity1 ┳ child-value-object1
┃ ┠ ┃ ┗ child-value-object2
┃ ┠ ┗ root-entity2 ┳ child-value-object1
┃ ┠ ┗ child-value-object2
┃ ┠ services
┃ ┠ factory
┃ ┗ repository(インターフェース)
┗ tests
考慮した内容
層をフォルダ単位で分ける
図に従って、presentation, infrastructure, application, domainでフォルダを分けた。層をフォルダ単位で分けることで、内側の層のロジック呼び出しが1つ外の層からだけ呼ばれていることを把握しやすくなる。また、それぞれの層の役割が考慮しやすくなる。
presentation層はコントローラー群
このサービスへの外部からのリクエストを受信するコントローラーを集めてそこからapplication層のロジックを呼ぶことで、どこからapplication層のロジックが呼ばれるか分かりやすくなる。
infrastructure層はアダプター群
外へのリクエストを行うアダプターを管理する場所で、application層からの外部へのリクエストやdomain層でのentityレポジトリの実装が集まる。
application層とdomain層を分ける
appilication層とdomain層を明確に分けることで、ドメインモデル貧血症を防ぎやすい
domain.serviceとdomain.modelを分ける
ドメイン層に含まれるモデルとサービスを分けることで、ドメインオブジェクトが持つべきルールと複数のドメインオブジェクトにまたがる処理の境界が明確になり、ドメインモデル貧血症を防ぎやすい
domain.modelをroot entity名で区切る
domain.modelは集約毎のルートエンティティを最上位のフォルダとして持ち、その中に集約内の子ドメインオブジェクトを入れていくことで、集約が把握しやすくなる。
testフォルダはappの外
図内のTestsはユースケースが意図通りに実装できているかの確認のためのテストであり、これはappの外のフォルダに配置している
Discussion