spring bootで始めるddd
TRANSCRIPT
Spring Bootで始めるDDD
ドメイン駆動設計導入 第一章
今日話すこと
● DDDを実際の開発に導入するためにやったこと
● Spring BootでDDDを実現するために行なったこと
● 既存システムをDDDで置き換えるためにやっていく予定のこと
DDD導入の背景
サービスの成長と複雑度の増加
● サービスの拡大
● 開発メンバーの増加
● アプリケーション知識の複雑化
● 開発・テスト工数の増大
トランザクションスクリプト
public void updateXxx(Long value) { Xxx xxx = dto.selectXxx(value); if (xxx.xxx = "xxx") { xxx.setFoo("XXX"); dto.updateXxx(xxx); dto.updateXxx(xxx); } else if (xxx.xxx = "YYY") { ... ... }}public void updateYYY(Long value) { YYY yyy = dto.selectYYY(value);
クラス名 = ネームスペース
手続き的な命名
条件のハードコード
類似コードの量産
利口なUI
出し分け条件等をViewが持っているデータ取得の処理や条件をViewが持っ
ている
データ不整合
Entity
Entity Entity
LogicA
LogicB
LogicC更新
更新
更新
データの整合性が担保できない!
DDDの適用レベル
レベル0
レベル1
レベル2
レベル3
ビジネス的な概念がコードにも設計にも反映されていない状態
ビジネスの価値や目標が明確になっている状態
ビジネスの用語や概念がコードに反映されている状態
ビジネスの領域が明確でサービスに反映されている状態
DDD導入までのステップ
何はなくとも聖書の購入
▶ 一人で読んでみる
▶ とりあえずドメインモデルを書いてみる
▶ コードを書いてみる
▶ 枕の下に敷いて寝る
有志による社内輪読会の開催
● 4〜5名の有志による輪読会
● 書籍の読み上げ、ディスカッション
● 週2時間 x 約5ヶ月
▶ 複数人で読んでみる
▶ 声に出して読み上げる
▶ それぞれの解釈を議論する
用語の統一、設計観の共有
戦術的DDDの部分導入による効果実証
LogicA
LogicB
Repository
Service
Controller
LogicC
▶ 既存ロジックの置き換え
▶ Entity/Repository/VOの適用
テスタビリティ・保守性向上の実感
意思決定者への導入提案
● 意思決定者が技術寄りの場合○ モジュラリティ・テスタビリティの向上
○ サービス品質の向上
○ アジリティの向上
● 意思決定者が非技術者寄りの場合○ コアドメイン=「金のなる木」
○ ビジネス的価値の追求
○ 変化への対応能力の向上
▶ 問題点の合意
▶DDD導入におけるメリットのPR
全員が納得できるDDD導入
パイロットプロジェクトでのDDD導入
ユースケース分析
ドメインモデル分析
戦術的DDD導入
新規プロジェクト
▶ 分析・モデリングの実施
▶ DDDパターンの実践
実現性の実証
NEXT) コンテキスト分割によるサービス設計
<<Root>>Job
<<Root>>Candidate
<<Root>>Application
<<Entity>>Resume
<<ValueObject>>XXXX
<<DomainEvent>>YYYY
<<ValueObject>>ZZZ
<<Root>>NewEntity
<<Entity>>JobId
ドメインモデリング
ユースケース分析・ドメインモデリング
記事の投稿ができる
記事の承認ができる
プロフィールを変更できる
ユースケース記述
▶ 名詞と振る舞いの用語の抽出
▶ ユースケース・シナリオの作成
ドメインモデル
▶ ドメインモデルの作成
Step1) ユースケースを書いてみる
記事の投稿ができる
記事の承認ができる
プロフィールを変更できる
記事の却下ができる
投稿者
管理者
記事の削除ができる
承認者
Step2) ユースケースシナリオを書いてみる
記事の承認1) 投稿者は新規記事を作成し、記事を保存する2) 投稿者は記事の承認依頼を出す3) 承認者は記事の承認状態を確認し、記事を承認する
Step3) ドメインモデルを書いてみる
承認状態のロジックが複雑化した時に肥大化しそう。。。
Step4) ドメインモデルを改善してみる
承認申請履歴をただの値オブジェクトにし、状態管理の責務をサービスに移す
Step5) ユースケースシナリオに反映してみる
記事の承認1) 投稿者は新規記事を作成し、記事を保存する2) 投稿者は記事の承認を申請する3) 記事承認サービスは記事の承認依頼の承認申請履歴を記録する4) 承認者は記事の最後の承認申請履歴の依頼者を確認し、記事を承認する5) 記事承認サービスは承認済の承認申請履歴を記録する
ドメインエキスパートとの会話を、納得が行くまで繰り返す
step6) 集約を探す
step7) リポジトリを追加する
アプリケーション・アーキテクチャ
DDD実装のための1stステップ
▶ レイヤー化アーキテクチャの導入
▶ 戦術的DDDパターンの適用
技術スタック
Java8
Spring Boot
Flyway
Spring Data JPA Spring MVCGradle
レイヤー化アーキテクチャ(1)
● 緩やかなレイヤー化アーキテクチャ● 直接隣接していないレイヤーへのアクセ
スも許可する
ヘキサゴナルも試したいけど取り敢えず一歩ずつ...
レイヤー化アーキテクチャ(2)
Controller
Form
Form DTO
DTO
AppService
DomainService Repository Specification
Entity ValueObject
InfraService
プレゼンテーション層
アプリケーション層
ドメイン層
インフラ層
パッケージ構成
jp.co.hoge.sample.domain
aggrigate_root
entity
value_object
service
repository
● 集約ルート単位で分けておくと作業分担やリファクタリングが楽になる。
● 業務的に関連度の高いものをまとめられる。
コード解説
まとめ
DDD導入に至るまでに必要なこと
● とにかく本を読む
● DDDの思想や用語を共有できる仲間を増やす
● 実装イメージや運用イメージがつかめるまで実験をする
● 問題構造を明確にし、意思決定者や利害関係者にメリットを理解してもらう