LoginSignup
31
24

More than 5 years have passed since last update.

PlayFrameworkでプロジェクトを分割する

Last updated at Posted at 2015-03-24

はじめまして。Qiita初投稿の t_hirohata です。
よろしくお願いいたします。

弊社ではScalaで開発しており、最近ではDDDで設計しようという動きになっています。
新しくプロジェクトを作る際DDDの各レイヤ毎にプロジェクトを分割したので、その方法をご紹介させていただきます。

方針

今回作成するプロジェクトはレイヤードアーキテクチャで設計したため、以下の様な構造に分割します。

projectRoot
  ├─ application
  ├─ domain
  └─ infrastructure

また、

  • アプリケーション層はPlayアプリケーションでいいけど、ドメイン層・インフラストラクチャ層はPlayに依存させたくない・・
  • 上層から下層は呼び出せるけど、下層から上層は呼び出せないようにしたい・・

としたかったため、以下の方法で実現しました。

プロジェクト分割

build.sbt
// このプロジェクトは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でプロジェクトの分割、ついでに依存関係の強制の方法についてご紹介させていただきました。
まだまだペーペーのエンジニアなので至らぬ点があるかもしれません。
ご意見・ご指摘等ございましたら、お気軽にコメントお願い致します。

31
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
24