はじめまして。Qiita初投稿の t_hirohata です。
よろしくお願いいたします。
弊社ではScalaで開発しており、最近ではDDDで設計しようという動きになっています。
新しくプロジェクトを作る際DDDの各レイヤ毎にプロジェクトを分割したので、その方法をご紹介させていただきます。
方針
今回作成するプロジェクトはレイヤードアーキテクチャで設計したため、以下の様な構造に分割します。
projectRoot
├─ application
├─ domain
└─ infrastructure
また、
- アプリケーション層はPlayアプリケーションでいいけど、ドメイン層・インフラストラクチャ層はPlayに依存させたくない・・
- 上層から下層は呼び出せるけど、下層から上層は呼び出せないようにしたい・・
としたかったため、以下の方法で実現しました。
プロジェクト分割
// このプロジェクトはapplication、domain、infrastructureの集合である
lazy val root = (
project in file(".")
).aggregate(
application,
domain,
infrastructure
)
// アプリケーション層
// アプリケーション層はドメイン層・インフラ層に依存し、Playアプリケーションである
lazy val application = Project(
id = "application",
base = file("application")
).dependsOn(
domain,
infrastructure
).enablePlugins(
PlayScala
)
// ドメイン層
// ドメイン層はインフラ層に依存
lazy val domain = Project(
id = "domain",
base = file("domain")
).dependsOn(
infrastructure
).settings(
scalaSource in Compile := baseDirectory.value / "src" / "main" / "scala",
scalaSource in Test := baseDirectory.value / "src" / "test" / "scala"
)
// インフラ層
lazy val infrastructure = Project(
id = "infrastructure",
base = file("infrastructure")
).settings(
scalaSource in Compile := baseDirectory.value / "src" / "main" / "scala",
scalaSource in Test := baseDirectory.value / "src" / "test" / "scala"
)
これでビルドしてみると以下の様な構造になります。(もともとあったものを除く)
projectRoot
├─ application
│ ├─ app/
│ ├─ conf/
│ ├─ public/
│ └─ target/
├─ domain
│ ├─ src/
│ └─ target/
├─ infrastructure
│ ├─ src/
│ └─ target/
├─ project/
├─ target/
├─ activator
└─ build.sbt
これで今回作成したかったものを実現できました。
実行方法は以下の通りです。
$ ./activator "project application" run # ./activator "application/run" でも可
上記は、下記と同じです。
$ ./activator
[projectRoot] project application
[application] run
UI層について
あれ?UI層が分離できていないじゃん。と思う方もいらっしゃるかもしれません。
今回作成したもののアプリケーション層はPlayアプリケーションとなっており、ControllerとViewが分かれていますので、それで妥協しております。
妥協せずにやるのでしたら、アプリケーション層はただJSONを返すだけのRESTfulなAPIサーバとして実装し、UI層をPlayのViewではなく別で実装する方法が良いと思います。
そうすることによって、Android、iOS、WebなどのUIを別々に作ることができ、ドメインを使いまわせることになります。
最後に
長々と書いてしまいましたが、Playでプロジェクトの分割、ついでに依存関係の強制の方法についてご紹介させていただきました。
まだまだペーペーのエンジニアなので至らぬ点があるかもしれません。
ご意見・ご指摘等ございましたら、お気軽にコメントお願い致します。