Spring Bootで始めるDDD

33
Spring Bootで始めるDDD ドメイン駆動設計導入 第一章

Transcript of Spring Bootで始めるDDD

Page 1: Spring Bootで始めるDDD

Spring Bootで始めるDDD

ドメイン駆動設計導入 第一章

Page 2: Spring Bootで始めるDDD

今日話すこと

● DDDを実際の開発に導入するためにやったこと

● Spring BootでDDDを実現するために行なったこと

● 既存システムをDDDで置き換えるためにやっていく予定のこと

Page 3: Spring Bootで始めるDDD

DDD導入の背景

Page 4: Spring Bootで始めるDDD

サービスの成長と複雑度の増加

● サービスの拡大

● 開発メンバーの増加

● アプリケーション知識の複雑化

● 開発・テスト工数の増大

Page 5: Spring Bootで始める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);

クラス名 = ネームスペース

手続き的な命名

条件のハードコード

類似コードの量産

Page 6: Spring Bootで始めるDDD

利口なUI

出し分け条件等をViewが持っているデータ取得の処理や条件をViewが持っ

ている

Page 7: Spring Bootで始めるDDD

データ不整合

Entity

Entity Entity

LogicA

LogicB

LogicC更新

更新

更新

データの整合性が担保できない!

Page 8: Spring Bootで始めるDDD

DDDの適用レベル

レベル0

レベル1

レベル2

レベル3

ビジネス的な概念がコードにも設計にも反映されていない状態

ビジネスの価値や目標が明確になっている状態

ビジネスの用語や概念がコードに反映されている状態

ビジネスの領域が明確でサービスに反映されている状態

Page 9: Spring Bootで始めるDDD

DDD導入までのステップ

Page 10: Spring Bootで始めるDDD

何はなくとも聖書の購入

▶ 一人で読んでみる

▶ とりあえずドメインモデルを書いてみる

▶ コードを書いてみる

▶ 枕の下に敷いて寝る

Page 11: Spring Bootで始めるDDD

有志による社内輪読会の開催

● 4〜5名の有志による輪読会

● 書籍の読み上げ、ディスカッション

● 週2時間 x 約5ヶ月

▶ 複数人で読んでみる

▶ 声に出して読み上げる

▶ それぞれの解釈を議論する

用語の統一、設計観の共有

Page 12: Spring Bootで始めるDDD

戦術的DDDの部分導入による効果実証

LogicA

LogicB

Repository

Service

Controller

LogicC

▶ 既存ロジックの置き換え

▶ Entity/Repository/VOの適用

テスタビリティ・保守性向上の実感

Page 13: Spring Bootで始めるDDD

意思決定者への導入提案

● 意思決定者が技術寄りの場合○ モジュラリティ・テスタビリティの向上

○ サービス品質の向上

○ アジリティの向上

● 意思決定者が非技術者寄りの場合○ コアドメイン=「金のなる木」

○ ビジネス的価値の追求

○ 変化への対応能力の向上

▶ 問題点の合意

▶DDD導入におけるメリットのPR

全員が納得できるDDD導入

Page 14: Spring Bootで始めるDDD

パイロットプロジェクトでのDDD導入

ユースケース分析

ドメインモデル分析

戦術的DDD導入

新規プロジェクト

▶ 分析・モデリングの実施

▶ DDDパターンの実践

実現性の実証

Page 15: Spring Bootで始めるDDD

NEXT) コンテキスト分割によるサービス設計

<<Root>>Job

<<Root>>Candidate

<<Root>>Application

<<Entity>>Resume

<<ValueObject>>XXXX

<<DomainEvent>>YYYY

<<ValueObject>>ZZZ

<<Root>>NewEntity

<<Entity>>JobId

Page 16: Spring Bootで始めるDDD

ドメインモデリング

Page 17: Spring Bootで始めるDDD

ユースケース分析・ドメインモデリング

記事の投稿ができる

記事の承認ができる

プロフィールを変更できる

ユースケース記述

▶ 名詞と振る舞いの用語の抽出

▶ ユースケース・シナリオの作成

ドメインモデル

▶ ドメインモデルの作成

Page 18: Spring Bootで始めるDDD

Step1) ユースケースを書いてみる

記事の投稿ができる

記事の承認ができる

プロフィールを変更できる

記事の却下ができる

投稿者

管理者

記事の削除ができる

承認者

Page 19: Spring Bootで始めるDDD

Step2) ユースケースシナリオを書いてみる

記事の承認1) 投稿者は新規記事を作成し、記事を保存する2) 投稿者は記事の承認依頼を出す3) 承認者は記事の承認状態を確認し、記事を承認する

Page 20: Spring Bootで始めるDDD

Step3) ドメインモデルを書いてみる

承認状態のロジックが複雑化した時に肥大化しそう。。。

Page 21: Spring Bootで始めるDDD

Step4) ドメインモデルを改善してみる

承認申請履歴をただの値オブジェクトにし、状態管理の責務をサービスに移す

Page 22: Spring Bootで始めるDDD

Step5) ユースケースシナリオに反映してみる

記事の承認1) 投稿者は新規記事を作成し、記事を保存する2) 投稿者は記事の承認を申請する3) 記事承認サービスは記事の承認依頼の承認申請履歴を記録する4) 承認者は記事の最後の承認申請履歴の依頼者を確認し、記事を承認する5) 記事承認サービスは承認済の承認申請履歴を記録する

ドメインエキスパートとの会話を、納得が行くまで繰り返す

Page 23: Spring Bootで始めるDDD

step6) 集約を探す

Page 24: Spring Bootで始めるDDD

step7) リポジトリを追加する

Page 25: Spring Bootで始めるDDD

アプリケーション・アーキテクチャ

Page 26: Spring Bootで始めるDDD

DDD実装のための1stステップ

▶ レイヤー化アーキテクチャの導入

▶ 戦術的DDDパターンの適用

Page 27: Spring Bootで始めるDDD

技術スタック

Java8

Spring Boot

Flyway

Spring Data JPA Spring MVCGradle

Page 28: Spring Bootで始めるDDD

レイヤー化アーキテクチャ(1)

● 緩やかなレイヤー化アーキテクチャ● 直接隣接していないレイヤーへのアクセ

スも許可する

ヘキサゴナルも試したいけど取り敢えず一歩ずつ...

Page 29: Spring Bootで始めるDDD

レイヤー化アーキテクチャ(2)

Controller

Form

Form DTO

DTO

AppService

DomainService Repository Specification

Entity ValueObject

InfraService

プレゼンテーション層

アプリケーション層

ドメイン層

インフラ層

Page 30: Spring Bootで始めるDDD

パッケージ構成

jp.co.hoge.sample.domain

aggrigate_root

entity

value_object

service

repository

● 集約ルート単位で分けておくと作業分担やリファクタリングが楽になる。

● 業務的に関連度の高いものをまとめられる。

Page 31: Spring Bootで始めるDDD

コード解説

Page 32: Spring Bootで始めるDDD

まとめ

Page 33: Spring Bootで始めるDDD

DDD導入に至るまでに必要なこと

● とにかく本を読む

● DDDの思想や用語を共有できる仲間を増やす

● 実装イメージや運用イメージがつかめるまで実験をする

● 問題構造を明確にし、意思決定者や利害関係者にメリットを理解してもらう