株式会社マネーパートナーズソリューションズ 
SpringBootを用いたドメイン駆動設計 
風間 淳一郎 
2014/11/27 JSUG勉強会 
今回の実装サンプルはこちらで確認できます 
https://github.com/jkazama/ddd-java
自己紹介 
風間 淳一郎 
株式会社マネーパートナーズソリューションズ システムマネジメント部部長。 
Web系のシステム開発を経験した後、2004年より金融系の開発に従事。 
2007年より現職。SpringFrameworkは2004年から利用。 
GitHub: https://github.com/jkazama 
Twitter: https://twitter.com/jkazama77 
株式会社マネーパートナーズ 
外国為替証拠金取引やCFD、有価証券買付けな どを行っている金融事業者。 
HP: http://www.moneypartners.co.jp
Spring利用経緯とSpringBootに至るまで 
ドメインモデリング 
ドメインモデリング実装例 
アジェンダ
Spring利用経緯とSpringBootに至るまで 
2008年 Spring2.5ベースでアーキを構築 
ポータル/フロント/バック/各種情報配信、全てを同一 基盤で開発 
今日紹介するドメインモデリングのアプローチを採用 
大量のデータソース/多数のサービス結合/マルチプロ セス(今だとマイクロサービス?)モデルに対応 
その多くが大規模リニューアル無しに現在まで 細かい変更/保守開発が継続している状況。
Spring利用経緯とSpringBootに至るまで 
2013年 新基盤の導入を検討 
老朽化するJavaアーキテクチャと技術的閉塞感 (Java6ベース) 
リファクタしても残る長大なコード、設定、保 守工数の増大 
マルチチャネル対応の必要性(サーバ側のAPI化) 
言語仕様の限界?
Spring利用経緯とSpringBootに至るまで 
2014年8月 マネパカードサービス開始 
ユースケース400over/他サービス連携も含めそ れなりの規模を消化 
新基盤を用いてコード量の軽減やAPIサーバモ デルを確立 
ドメインアーキや実装は既存のものをかなり流用
Spring利用経緯とSpringBootに至るまで 
2014年8月 マネパカードサービス開始 
サーバ側はJavaではなくScalaを採用 
Rodも興味持ってたし… 
コンパイル時間以外、大きな問題も発生せず
Spring利用経緯とSpringBootに至るまで 
2014年8月 SpringBootの存在にようやく気づく 
槙さんのSpringBoot紹介資料を拝見 
SpringはSpringRooとかの流れとライブラリ 肥大化で勝手に終わったと思っていた 
SpringBoot(Spring4) + Lombok + Gradleを組 み合わせる事でJavaでも効果的な開発は可能 
どちらかというと終わっていたのは自分の方だった…
Spring利用経緯とSpringBootに至るまで 
前置きはここまで 
次からは今回サンプル題材とするドメインにつ いて簡単に解説します。
ドメインモデリング 
ドメイン概念自体はERモデリングの時代からある古い話です。 Javaの世界ではFowlerのPoEAA(2002)などで紹介された後、 EvansのDDD(2003)でうまいこと体系化されました。 
※厳密にそうなのかはちょっと自信ないですけど。 
上述の通り、かなり昔からある理論なのですが、内容が内容だ けに実装解釈の幅は結構広いです。今回紹介するJava実装例は あくまでその一事例としてご覧ください。
ドメインモデリング 
想定ユースケース(単純な出金ワークフロー) 
サービス事業者 
金融機関 
顧客 
システム(ジョブスケジューラ) 
[出金依頼] 
[出金依頼締め] 
[出金指示ファイル出力] 
[出金実現] 
T 
T + n 
T + 3 
依頼確定日(発生日)をTとします。 
※取引じゃないですが、分かりやすいので…
ドメインモデリング 
想定モデル 
必要最低限の要素だけを定義。 
入出金は振込に限らず振替や取引、両替 などからも生み出される。
ドメインモデリング 
今回のサンプルで利用するレイヤリング 
RESTfulAPI 
UI層 
Controller 
アプリケーション層 
Service 
ドメイン層 
Entity 
インフラ層 
DTO 
DTO 
SpringBoot 
Repository 
Library
ドメインモデリング 
今回のサンプルで利用するレイヤリング 
特徴 
オーソドックスな三層モデルを利用、UI層は APIベースのやり取りを想定 
各層からインフラ層へのアクセスを許容 
RepositoryとEntityの関係は1-1ではなく1-n
ドメインモデリング 
モデリングはこんな感じで大雑把にしました 
次からは実装例をお見せします。
ドメインモデリング実装例 
実装コード前提 
Java7以上でLombokを利用 
ドメイン実装がシンプルに見えるよう各種ライブラリ を用意済(後ほどGitHubでご確認ください) 
項目定義や例外処理などはかなり省略してます
ドメインモデリング実装例 
ドメイン層 – 振込入出金(CashInOut)> クラス定義/フィールド定義 
@Entityを定義してJPA概念と紐付け 
Lombokアノテーションで最低限の必要処理を追加 
JpaActiveRecordを継承してCRUDをサポート 
EntityではDIを用いない 
Logger等、シリアライズする際に問題となるクラスを インスタンス変数として持たない。 
フィールドでは@IdでIDを明示化 
制約アノテーションを用いてカラムドメイン定義を明示 
必要に応じて@Embeddedでフィールドクラスを分割 
@OneToMany等の関連定義は利用目的が抽象的になりが ちなのと、レイヤリングアーキでLAZYロードに起因する トラブルを解決するのが面倒なので利用していません。 
※EAGERフェッチ前提で割り切れるならOK
ドメインモデリング実装例 
ドメイン層 – 振込入出金(CashInOut)> 出金依頼(Entityを生成) 
既存出金依頼は存在しないため、クラスメソッドで生成 
営業日/日時、UID、設定パラメタなどは引数に取った Repositoryを利用してインフラ層から取得 
審査で問題なければ、関連情報を取得して振込入出金情報を永続化。
ドメインモデリング実装例 
ドメイン層 – 振込入出金(CashInOut)> 出金依頼DTO 
DTOはSerializableにしておく 
Lombokアノテーションで最低限の必要処理を追加 
UI層の入力チェックなどで利用されるのでフィールド単 位の制約定義はきちんと行う 
ドメイン層のDTOは粒度をユースケース単位で細かく作成していく事を推奨します。 
引数が3つ以上になり始めたらパラメタクラスの作成を考えてください。 
※以降の引数追加要求にI/F変更無しで対応できるようになります。 
ユースケース処理引数の粒度が粗ければ粗いほど、予期せぬ状態変更の副作用で苦しむ可能性が高くなります。
ドメインモデリング実装例 
ドメイン層 – 振込入出金(CashInOut)> 制約アノテーション 
制約アノテーションはデータモデリングにおけるドメインの解釈で 考えると分かりやすい(正規表現も利用可能) 
フィールド単位の共有カラムドメインを切り出して定義していく 
@NotNullを外して@AbsAmountEmptyなどのnull許容アノテー ションを合わせて用意しておくと可読性が増す 
BeanValidationでは制約定義の拡張が可能
ドメインモデリング実装例 
ドメイン層 – 振込入出金(CashInOut)> レポジトリ層アクセサ(dh) 
インフラ層のコンポーネントの中でドメイン層での利用を許可する ものを束ねたユーティリティヘルパ 
利用時はその特性上ネストアクセスが深くなりがちなので、なるべ く短いメソッド名で公開 
この他によく使われるコンポーネントは以下のようなものがある 
-営業日管理(休日概念やT+nの考慮) 
-アプリケーション設定(オンライン中の動的変更にも対応) 
-メッセージリソース(i18n)
ドメインモデリング実装例 
ドメイン層 – 振込入出金(CashInOut)> 利用ドメインクラス 
JPAの管理下に置かれないドメインクラス例 
複数Entityを口座資産という大きい概念で束ねている
ドメインモデリング実装例 
ドメイン層 – 振込入出金(CashInOut)> 出金依頼確定(自己の状態を変更) 
既存出金依頼をload後に呼び出すユースケース処理 
自身の情報を変更しつつ、依存する他Entityへ変更結果 を伝搬していく。
ドメインモデリング実装例 
アプリケーション層 – 資産(AssetService)> クラス定義 
@Serviceを定義してDIコンテナへ登録(シングルトン) 
ServiceSupportを継承してアプリケーション層の共通的 な振る舞いを実装 
Serviceではユースケース処理を記載していきます。基本的にControllerと1-1の関係となります。 
Serviceにおけるユースケース処理はドメインのユースケース処理よりもより広義な解釈となっており、トランザ クションや排他処理、メール送信や帳票出力、外接連携等の外部リソースと関連付く内容も含まれます。 
※非機能要件のチューニングなどもアプリケーション層の責務に含まれます。
ドメインモデリング実装例 
アプリケーション層 – 資産(AssetService)> サービス基底定義 
アプリケーション層ではドメイン層と異なり、インフラ層 のコンポーネントとより密接に紐付きます。 
メール送信や帳票出力などはドメイン概念が交じるので、 必要に応じてアプリケーション層でメール送信やレポート 出力のコンポーネントをラップします。 
今回は用意していませんが、スレッドやメッセージング を用いた非同期処理やマルチデータソースの管理なども アプリケーション層の責務となります。
ドメインモデリング実装例 
アプリケーション層 – 資産(AssetService)> 振込出金依頼 
ユースケース処理では利用者行為の監査ログを残したり、 排他ロックやトランザクション制御などを行いつつ、ドメ イン層のユースケース処理へ繋いでいく 
非同期処理系は事前にトランザクションの確定保証が必要 
(JTAや非同期系のトランザクション概念を混ぜない場合) 
実行した際のコンソール出力例
ドメインモデリング実装例 
アプリケーション層 – 資産(AssetService)> メール送信クラス 
インフラ層の単純なMailHandlerを、アプリケーション層 でラップしてドメイン概念を加えている例
ドメインモデリング実装例 
アプリケーション層 – 資産(AssetAdminService)> 振込出金依頼締め 
ジョブスケジューラから呼び出される口座横断的な処理 
冗長になりやすいので、トランザクション内部の処理は切り出し 
対象を抜き出した後に必要処理を個別実施 
ここではジョブ実行中のオンライン要求を許可する前提で実装し ているので、口座単位にアカウントロックを掛けている 
ここでのジョブは差分更新を許容したいので、失敗時は例外が上 位に飛ばないようにしている(個別例外はログ監視で検知) 
※実際はもう少しトランザクション粒度を細かくすべき
ドメインモデリング実装例 
UI層 – 資産(AssetController)> クラス定義/振込出金依頼 
@RestControllerを定義してDIコンテナへ登録(シングルトン) 
@RequestMappingでURLを紐付け 
利用するサービスをDI 
顧客向けなどでEntityが過剰に情報を持っている時(更新者や内 部管理項目 等)は表示用のDTOへ詰替え 
引数DTOに@Validを付与する事で、事前にDTOで定義していた カラムドメインの定義に応じたBeanValidationのチェックが発 生する
ドメインモデリング実装例 
UI層 – ジョブ(JobController)> クラス定義/振込出金依頼締め 
ジョブスケジューラから叩かれる際の受け口 
ユースケース上の利用者はシステムとなる 
戻り値を定義するかはジョブスケジューラの仕様に応じて
ドメインモデリング実装例 
アプリケーション起動クラス 
SpringBoot1.2ではこれだけ 
@SpringBootApplicationは内部で@Configuration/ 
@EnableAutoConfiguration/@ComponentScanを呼び 出している 
設定ファイルはXMLの代わりにこんな感じで application.yml定義を書くだけ 
通常のJavaアプリケーションとしてApplicationクラスを 実行するだけで、Tomcatを内包した常駐プロセスが起動
ドメインモデリング実装例 
まとめ 
SpringBootを利用することで記述量が減る 
構造がシンプルになる分、ドメインに集中できる 
Lombokを利用することで記述量が減る 
実装の内容を考えると、Java8やGroovyを使うと もっとシンプルにできる 
導入の敷居の高さは会社毎に違うので今回はJava7前提
ドメインモデリング実装例 
以上です、ご清聴ありがとうございました。 
時間が残っていれば簡単なデモ見せます。
おまけ 
自社で作っているものの簡単な紹介 [SpringBootベースのフレームワーク] 
設計成果物を開発リソースへと繋ぐ。(開発立ち上げを早く!) 
自動生成は支援ツールと割り きって、単方向のみのサポー トを想定 
開発生産性の向上。エンタープライズ要件をシンプルに! 
認証・認可 
ビルド/リリース/運用を簡略化。 
+ 
mpx-tools
プロセス 
三層サポート 
おまけ 
自社で作っているものの簡単な紹介 [SpringBootベースのフレームワーク] 
ライブラリはインフラ層のサポートをなるべく手厚く 
ライブラリ群 
日付/日時 
POJO(BeanSupport) 
設定 
ログ 
型変換 
フォーマット 
審査 
スケジューラ 
非同期 
認証/認可 
DB 
MQ 
メール 
レポーティング 
IDロック 
監査/イベント/メールログ 
ドメイン審査 
i18n 
利用者管理 
Webサーバ 
MQサーバ 
DIコンテナ(SpringBoot) 
リモーティング 
分散キャッシュ制御 
スレッド管理 
分散コンポーネント管理
おまけ 
自社で作っているものの簡単な紹介 [SpringBootベースのフレームワーク] 
マルチデータソース利用の例
おまけ 
自社で作っているものの簡単な紹介 [SpringBootベースのフレームワーク] 
使ってみたい方とか、基盤の仕組みに興味あ る方はこちらまで問合せお願いします。 
株式会社マネーパートナーズソリューションズ 
営業担当:武田 
info@mpsol.co.jp 
03-4540-3890

JSUG 20141127 「Spring Bootを用いたドメイン駆動設計」