Contenu connexe
Similaire à JSUG 20141127 「Spring Bootを用いたドメイン駆動設計」 (20)
JSUG 20141127 「Spring Bootを用いたドメイン駆動設計」
- 2. 自己紹介
風間 淳一郎
株式会社マネーパートナーズソリューションズ システムマネジメント部部長。
Web系のシステム開発を経験した後、2004年より金融系の開発に従事。
2007年より現職。SpringFrameworkは2004年から利用。
GitHub: https://github.com/jkazama
Twitter: https://twitter.com/jkazama77
株式会社マネーパートナーズ
外国為替証拠金取引やCFD、有価証券買付けな どを行っている金融事業者。
HP: http://www.moneypartners.co.jp
- 17. ドメインモデリング実装例
ドメイン層 – 振込入出金(CashInOut)> クラス定義/フィールド定義
@Entityを定義してJPA概念と紐付け
Lombokアノテーションで最低限の必要処理を追加
JpaActiveRecordを継承してCRUDをサポート
EntityではDIを用いない
Logger等、シリアライズする際に問題となるクラスを インスタンス変数として持たない。
フィールドでは@IdでIDを明示化
制約アノテーションを用いてカラムドメイン定義を明示
必要に応じて@Embeddedでフィールドクラスを分割
@OneToMany等の関連定義は利用目的が抽象的になりが ちなのと、レイヤリングアーキでLAZYロードに起因する トラブルを解決するのが面倒なので利用していません。
※EAGERフェッチ前提で割り切れるならOK
- 18. ドメインモデリング実装例
ドメイン層 – 振込入出金(CashInOut)> 出金依頼(Entityを生成)
既存出金依頼は存在しないため、クラスメソッドで生成
営業日/日時、UID、設定パラメタなどは引数に取った Repositoryを利用してインフラ層から取得
審査で問題なければ、関連情報を取得して振込入出金情報を永続化。
- 19. ドメインモデリング実装例
ドメイン層 – 振込入出金(CashInOut)> 出金依頼DTO
DTOはSerializableにしておく
Lombokアノテーションで最低限の必要処理を追加
UI層の入力チェックなどで利用されるのでフィールド単 位の制約定義はきちんと行う
ドメイン層のDTOは粒度をユースケース単位で細かく作成していく事を推奨します。
引数が3つ以上になり始めたらパラメタクラスの作成を考えてください。
※以降の引数追加要求にI/F変更無しで対応できるようになります。
ユースケース処理引数の粒度が粗ければ粗いほど、予期せぬ状態変更の副作用で苦しむ可能性が高くなります。
- 20. ドメインモデリング実装例
ドメイン層 – 振込入出金(CashInOut)> 制約アノテーション
制約アノテーションはデータモデリングにおけるドメインの解釈で 考えると分かりやすい(正規表現も利用可能)
フィールド単位の共有カラムドメインを切り出して定義していく
@NotNullを外して@AbsAmountEmptyなどのnull許容アノテー ションを合わせて用意しておくと可読性が増す
BeanValidationでは制約定義の拡張が可能
- 21. ドメインモデリング実装例
ドメイン層 – 振込入出金(CashInOut)> レポジトリ層アクセサ(dh)
インフラ層のコンポーネントの中でドメイン層での利用を許可する ものを束ねたユーティリティヘルパ
利用時はその特性上ネストアクセスが深くなりがちなので、なるべ く短いメソッド名で公開
この他によく使われるコンポーネントは以下のようなものがある
-営業日管理(休日概念やT+nの考慮)
-アプリケーション設定(オンライン中の動的変更にも対応)
-メッセージリソース(i18n)
- 22. ドメインモデリング実装例
ドメイン層 – 振込入出金(CashInOut)> 利用ドメインクラス
JPAの管理下に置かれないドメインクラス例
複数Entityを口座資産という大きい概念で束ねている
- 23. ドメインモデリング実装例
ドメイン層 – 振込入出金(CashInOut)> 出金依頼確定(自己の状態を変更)
既存出金依頼をload後に呼び出すユースケース処理
自身の情報を変更しつつ、依存する他Entityへ変更結果 を伝搬していく。
- 24. ドメインモデリング実装例
アプリケーション層 – 資産(AssetService)> クラス定義
@Serviceを定義してDIコンテナへ登録(シングルトン)
ServiceSupportを継承してアプリケーション層の共通的 な振る舞いを実装
Serviceではユースケース処理を記載していきます。基本的にControllerと1-1の関係となります。
Serviceにおけるユースケース処理はドメインのユースケース処理よりもより広義な解釈となっており、トランザ クションや排他処理、メール送信や帳票出力、外接連携等の外部リソースと関連付く内容も含まれます。
※非機能要件のチューニングなどもアプリケーション層の責務に含まれます。
- 25. ドメインモデリング実装例
アプリケーション層 – 資産(AssetService)> サービス基底定義
アプリケーション層ではドメイン層と異なり、インフラ層 のコンポーネントとより密接に紐付きます。
メール送信や帳票出力などはドメイン概念が交じるので、 必要に応じてアプリケーション層でメール送信やレポート 出力のコンポーネントをラップします。
今回は用意していませんが、スレッドやメッセージング を用いた非同期処理やマルチデータソースの管理なども アプリケーション層の責務となります。
- 26. ドメインモデリング実装例
アプリケーション層 – 資産(AssetService)> 振込出金依頼
ユースケース処理では利用者行為の監査ログを残したり、 排他ロックやトランザクション制御などを行いつつ、ドメ イン層のユースケース処理へ繋いでいく
非同期処理系は事前にトランザクションの確定保証が必要
(JTAや非同期系のトランザクション概念を混ぜない場合)
実行した際のコンソール出力例
- 28. ドメインモデリング実装例
アプリケーション層 – 資産(AssetAdminService)> 振込出金依頼締め
ジョブスケジューラから呼び出される口座横断的な処理
冗長になりやすいので、トランザクション内部の処理は切り出し
対象を抜き出した後に必要処理を個別実施
ここではジョブ実行中のオンライン要求を許可する前提で実装し ているので、口座単位にアカウントロックを掛けている
ここでのジョブは差分更新を許容したいので、失敗時は例外が上 位に飛ばないようにしている(個別例外はログ監視で検知)
※実際はもう少しトランザクション粒度を細かくすべき
- 29. ドメインモデリング実装例
UI層 – 資産(AssetController)> クラス定義/振込出金依頼
@RestControllerを定義してDIコンテナへ登録(シングルトン)
@RequestMappingでURLを紐付け
利用するサービスをDI
顧客向けなどでEntityが過剰に情報を持っている時(更新者や内 部管理項目 等)は表示用のDTOへ詰替え
引数DTOに@Validを付与する事で、事前にDTOで定義していた カラムドメインの定義に応じたBeanValidationのチェックが発 生する
- 30. ドメインモデリング実装例
UI層 – ジョブ(JobController)> クラス定義/振込出金依頼締め
ジョブスケジューラから叩かれる際の受け口
ユースケース上の利用者はシステムとなる
戻り値を定義するかはジョブスケジューラの仕様に応じて
- 31. ドメインモデリング実装例
アプリケーション起動クラス
SpringBoot1.2ではこれだけ
@SpringBootApplicationは内部で@Configuration/
@EnableAutoConfiguration/@ComponentScanを呼び 出している
設定ファイルはXMLの代わりにこんな感じで application.yml定義を書くだけ
通常のJavaアプリケーションとしてApplicationクラスを 実行するだけで、Tomcatを内包した常駐プロセスが起動
- 35. プロセス
三層サポート
おまけ
自社で作っているものの簡単な紹介 [SpringBootベースのフレームワーク]
ライブラリはインフラ層のサポートをなるべく手厚く
ライブラリ群
日付/日時
POJO(BeanSupport)
設定
ログ
型変換
フォーマット
審査
スケジューラ
非同期
認証/認可
DB
MQ
メール
レポーティング
IDロック
監査/イベント/メールログ
ドメイン審査
i18n
利用者管理
Webサーバ
MQサーバ
DIコンテナ(SpringBoot)
リモーティング
分散キャッシュ制御
スレッド管理
分散コンポーネント管理