DDD on Scala
はじめに
Scala による DDD(ドメイン駆動設計) の実装サンプルです。
Scalaの関数型言語の特徴を活かして、 イミュータブル で 副作用のない(副作用を局所化した) DDDの実装を目指しています。
当サンプルの解説は、 こちらのスライド を参照してください。
Note
|
実装上のポイントを、コード中に |
セットアップ
前提
-
JDK 1.8 以上
DBの準備
このサンプルでは、一部で 組み込みのH2データベース を使用したコード例があります。
サンプルの実行前にDBを作成します。
-
sbt でDBにテーブルを作成します。
$ sbt "project rdb" flywayMigrate
ビルドと実行
このサンプルはアプリケーションとしてのエンドポイントはありません。
動作は sbt からユニットテストを実行して確認してください。
$ sbt test
構成
レイヤ・モジュール構成
このサンプルでは、 オニオンアーキテクチャ をもとにした レイヤ・モジュール構成を採用しています。
レイヤ |
責務 |
依存するレイヤ |
ドメイン |
ドメイン(業務)の関心事と仕様をモデル化します。 |
なし |
アプリケーション |
ドメインを使用して、ユースケースを実現します。 |
ドメイン |
クエリ |
|
なし |
インフラストラクチャ |
アプリケーションの実行結果を永続化します。 |
アプリケーション / ドメイン / クエリ |
インターフェース |
利用者へのユーザーインターフェースを提供します。 |
インフラストラクチャ / アプリケーション / ドメイン / クエリ |
-
ドメインレイヤ
とアプリケーションレイヤ
は特定のインフラストラクチャに依存しないので、 インフラストラクチャの変更が容易になります。
また、インフラストラクチャをモック化することも容易なので、ユニットテストを簡単かつ軽量に実施することができます。 -
インフラストラクチャレイヤ
は、採用するミドルウェア・サービスごとにモジュールを分割します。
こうすることで、インターフェースレイヤ
でインフラストラクチャモジュールを実行に必要なものだけに限定することができ、 使用しないライブラリ(JDBCドライバやクライアントライブラリなど)のために実行モジュールが肥大化することを回避できます
特にAWS Lambda
などのサーバレスプラットフォームでは、実行モジュールが大きくなると実行時のスピンアップ時間が長くなるため、 実行モジュールを小さくすることに価値があります。 -
インターフェースレイヤ
は、提供するインターフェース(Web画面、REST API、CLIなど)ごとにモジュールを分割します。
参考文献
Scala
-
ドワンゴさんのScala研修用テキスト
Scalaの入門テキスト。 -
HishidamaさんのScalaリファレンス
Scalaのよく使う言語機能やAPIのリファレンス。 -
ScalaTest
Scalaの代表的なテスティングライブラリ。 -
ScalikeJDBC
ScalaでRDBにアクセスするライブラリ。 -
Returning the "Current" Type in Scala
スーパータイプのメソッドの戻り値の型として、サブタイプを使用する方法の解説。
DDD(ドメイン駆動設計)
-
Scalaコードでわかった気になるDDD
Scalaを使ったDDDの解説。 -
DDD実践(ベスト)プラクティス{ドメインイベントとマイクロサービスと組織の関係}
CQRSパターンとドメインイベント/イベントソーシングの解説。
その他
-
AsciiDoc cheatsheet
AsciiDoc(このREADMEでも使用しているマークダウン言語)の書き方。一般的な Markdown よりも表現力が強力。