Spring Bootで始めるDDD

Post on 15-Feb-2017

289 views 5 download

Transcript of Spring Bootで始めるDDD

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の思想や用語を共有できる仲間を増やす

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

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