SlideShare uma empresa Scribd logo
1 de 45
Baixar para ler offline
© BIGLOBE Inc.
ドメイン駆動設計
失敗したことと成功したこと
2018/9/26
ビッグローブ株式会社
小林 映里奈
2 © BIGLOBE Inc.
自己紹介
小林 映里奈(こばやし えりな)
• @eri_twin
• 2015年度入社の4年目
所属、担当業務
• ITシステム本部 ビッグローブ光開発チーム
• ビッグローブ光の業務システムの開発
3 © BIGLOBE Inc.
今日のテーマ
失敗したことと成功したこと
4 © BIGLOBE Inc.
ドメイン駆動設計への愛をこめて!
5 © BIGLOBE Inc.
agenda
◆ ドメイン欠乏症との戦い ~実践と結果~
◆ つらい現実からドメインを守る 3つの盾
・Form
・Converter
・Adapter
6 © BIGLOBE Inc.
ドメイン欠乏症との戦い ~実践と結果~
「ドメインにロジックを書く」を実現するための試行錯誤
7 © BIGLOBE Inc.
ドメイン欠乏症
手続き型のイメージで、ドメイン以外にロジックを書いてしまう
↓アプリケーション層にロジックがある例
8 © BIGLOBE Inc.
ドメイン欠乏症
ドメインが出てこない…
👉 業務ロジックなど、業務の関心事は
ドメインに書こう!
たとえば、
前提条件のチェックは業務ロジック。
他には?
9 © BIGLOBE Inc.
なにをドメインに書くべきか
Q. どこまでがドメイン(=業務ロジック)なのか
業務ロジックに該当しそうなもの、たとえば
- 業務に関連するドメインを取得する
- 各ドメインが業務の前提条件を満たしているかチェック
- ドメインの状態を変更する
- 変更された状態のドメインを永続化する
etc…
10 © BIGLOBE Inc.
なにをドメインに書くべきか
Q. どこまでがドメイン(=業務ロジック)なのか
業務ロジックに該当しそうなもの、たとえば
- 業務に関連するドメインを取得する
- 各ドメインが業務の前提条件を満たしているかチェック
- ドメインの状態を変更する
- 変更された状態のドメインを永続化する
etc…
A. 関連ドメインの取得・チェック・状態変更までを
ドメインで扱う業務とする
11 © BIGLOBE Inc.
ドメインの責務はここ
12 © BIGLOBE Inc.
ドメイン欠乏症対策
👉 関連ドメイン取得のためドメイン層でリポジトリのDI
👉 前提条件チェック、変更後のエンティティ返却がドメインの責務
↓ドメイン層のOrderDateにロジックを委譲
13 © BIGLOBE Inc.
ドメイン欠乏症対策
👉 業務ロジックをドメインに委譲
👉 if文がなくなって見通しが良くなった
↓アプリケーション層はシンプルに
14 © BIGLOBE Inc.
ドメイン欠乏症対策
🙆 ドメイン層にビジネスロジックがまとまる
🙆 アプリケーション層の見通しを良くできた
🙅‍リポジトリへのアクセスが入るため副作用が多く、
ドメイン層のテストがつらい
→ モック化すればいいと思ってたけど、それも大変だった
→ 実際やってみると、ドメインに集めすぎた感がある
どこまでを業務(ドメイン)とみなすか、考え直す
15 © BIGLOBE Inc.
続:なにをドメインに書くべきか
Q. どこまでがドメイン(=業務ロジック)なのか
業務ロジックに該当しそうなもの、たとえば
- 業務に関連するドメインを取得する
- 各ドメインが業務の前提条件を満たしているかチェック
- ドメインの状態を変更する
- 変更された状態のドメインを永続化する
etc…
A. リポジトリへのアクセスはアプリケーション層へ
チェック・状態変更までをドメインで扱う業務とする
16 © BIGLOBE Inc.
続:ドメインの責務はここ
17 © BIGLOBE Inc.
ドメイン
👉 必要な情報を受け取り、
イベント = 永続化に必要な情報をまとめたクラス を作る
👉 ドメインの内部に閉じたロジックはドメインに書く
18 © BIGLOBE Inc.
ドメインサービス
👉 ドメインサービス(ドメイン層)
👉 ドメインサービスは業務の単位で分けている。
例では申込のユースケースなので、申込に関する業務ロジックを持つ
19 © BIGLOBE Inc.
APサービス全体像
イベントを作る
永続化
20 © BIGLOBE Inc.
ドメイン欠乏症対策2
🙆 サービス層の見通しが良い
🙆 リポジトリアクセス→イベント作成→永続化 の流れが
わかりやすい
🙆‍副作用がないので、ドメイン層はテストしやすい
これが今のところ良いかんじなので、継続中
Q.‍最初にすべてのエンティティを取得するのは冗長?
余計なリポジトリアクセスが多いのでは?
A. そうでもない。
想定よりも無駄になるエンティティはかなり少なかった。
21 © BIGLOBE Inc.
中身のつまったドメインをつくろう!
22 © BIGLOBE Inc.
つらい現実からドメインを守る 3つの盾
内部ではドメインを充実させていく一方、
外部からはさまざまな現実が攻めてきます
23 © BIGLOBE Inc.
現実の世界
domain
service
infrastructure
現実は想定外のさまざまなことが起きる
お店の説明と違う!
クーリングオフ
したいです
オーダー修正する時は
XXのYYをZZZにして
さらにAAAのBBを…
このパターンの番号体系
が昨⽇日からS-­inしました
K社
N社
ドメインの状態にはないけど、
契約開始後キャンセルが必要…
⼀一旦オーダーを取消
してやりなおします
ええー!!
24 © BIGLOBE Inc.
domain
application
infrastructure
user
interface
DB
formAPI
File
converter adapter
つらい現実からドメインを守る💪
3つの盾
👉 form/request: 複雑なバリデーションルールから守る
👉 converter: 複雑なIF仕様から守る
👉 adapter: 物理データ構造から守る
25 © BIGLOBE Inc.
domain
application
infrastructure
user
interface
DB
formAPI
File
converter adapter
つらい現実からドメインを守る💪
3つの盾
👉 form/request: 複雑なバリデーションルールから守る
👉 converter: 複雑なIF仕様から守る
👉 adapter: 物理データ構造から守る
26 © BIGLOBE Inc.
複雑なバリデーションルールのつらみ
😭 APIが多すぎる!
→ 申込経路によってサービス仕様が違う
→ 経路Aと経路Bでバリデーションを分けたい
→ APIをユースケース単位で作成するので数が増える
→ 同じ商品の新規申込APIが50本とかあるような規模
😭 ドメイン層がバリデーションルールで汚れてしまう
🎈 form/requestとは
バリデーションルールをユーザインターフェース層に出し
APIや経路ごとにバリデーションを管理する!
27 © BIGLOBE Inc.
Form
👉 @Patternにオブジェクトのバリデーションルールを書く
👉 ドメインオブジェクトに変換して返すgetterを用意
パラメータごとにXX(ドメイン名)Formを作る
ex) ユーザIDを受け取るためのUserIdForm
28 © BIGLOBE Inc.
Request
👉 先述のFormクラスをまとめたリクエストクラス
API単位のリクエストパラメータを表現している
👉 API固有のパラメータの必須/非必須や相関チェックをここで管理する
👉 Formの値がnullだとオブジェクトをgetしたときに例外になるので
nullの場合はバリデーションエラーにするアノテーションを作った
(@ValueObjectNotEmpty)
29 © BIGLOBE Inc.
API
👉 リクエストで受け取ったパラメータを
バリデーション済みのオブジェクトとして取り出す
30 © BIGLOBE Inc.
domain
application
infrastructure
user
interface
DB
formAPI
File
converter adapter
つらい現実からドメインを守る💪
3つの盾
👉 form/request: 複雑なバリデーションルールから守る
👉 converter: 複雑なIF仕様から守る
👉 adapter: 物理データ構造から守る
💪
守った!
31 © BIGLOBE Inc.
domain
application
infrastructure
user
interface
DB
formAPI
File
converter adapter
つらい現実からドメインを守る💪
3つの盾
👉 form/request: 複雑なバリデーションルールから守る
👉 converter: 複雑なIF仕様から守る
👉 adapter: 物理データ構造から守る
💪
32 © BIGLOBE Inc.
複雑なIF仕様のつらみ
😭 大企業様から提供されるIF仕様書はむずかしい
→ 写し間違えて項目ずれるの怖い
→ 項目数が多いと確認も大変
😭 社内と社外では世界観が違う
→ ドメインモデルと異なる形のデータ群を求められる
→ せっかく作ったモデルはIF仕様に引っ張られたくない…
🎈 Converterとは
複雑なIF仕様をそのままコードに落とす!
外部都合のIFから自分たちのドメインモデルを守る!
33 © BIGLOBE Inc.
Converter: 複雑なIF仕様から守る
IF仕様書をそのままコードに落とす
👉 外部のドメインと自分たちのドメインの言葉を紐付ける
このクラスのコードが言葉の差を埋める設計資料そのものになる
👉 どのエンティティのフィールドかひと目でわかる
ex) v.会員()は会員エンティティにあるデータを使っている
👉 サンプルデータをそのまま期待値に使ったテストが書ける!
↑外部のドメイン
⾃自分たちのドメイン
34 © BIGLOBE Inc.
Converter: 複雑なIF仕様から守る
ドメインモデルの世界観を守る
👉 IFの契約者住所はアパート名を含むが、モデルは住所とアパート名が別
👉 converterで住所とアパート名を繋げたデータを作る
👉 モデルは変えず、IF仕様との世界観の差はconverterが吸収する
35 © BIGLOBE Inc.
domain
application
infrastructure
user
interface
DB
formAPI
File
converter adapter
つらい現実からドメインを守る💪
3つの盾
👉 form/request: 複雑なバリデーションルールから守る
👉 converter: 複雑なIF仕様から守る
👉 adapter: 物理データ構造から守る
💪 💪
36 © BIGLOBE Inc.
domain
application
infrastructure
user
interface
DB
formAPI
File
converter adapter
つらい現実からドメインを守る💪
3つの盾
👉 form/request: 複雑なバリデーションルールから守る
👉 converter: 複雑なIF仕様から守る
👉 adapter: 物理データ構造から守る
💪 💪
37 © BIGLOBE Inc.
物理データのつらみ
前提:O/RマッパーはMyBatisを使っている
😭 データをエンティティに変換するマッピングがつらい
38 © BIGLOBE Inc.
物理データのつらみ
Q. Javaのクラス自動生成してくれるO/RM使わないの?
A. 扱うデータ量が非常に多いので、チューニング必須。
SQLをカスタマイズしやすいO/RMを使いたい。
MyBatisのよいところ
👉 SQLを直に書ける(チューニングできる) (超大事)
MyBatisのつらいところ
👉 xmlでマッピングを書くのが大変
👉 コンパイルエラーにならないので実行時エラーが出る
👉 エラーがわかりにくいので原因の調査に苦労する
🎈 Adapterとは
よいところだけを活かす!
MyBatisを使いながらマッピングはJavaで行う!
39 © BIGLOBE Inc.
Adapter
Javaの基本的なクラスでDBから値を取得する。
👉 VARCHER型はString, DATE型はLocalDate(LocalDateTime)
👉 値を取得する段階ではバリューオブジェクトへの変換処理はしない
バリューオブジェクトへの変換ロジックはadapterに集める
40 © BIGLOBE Inc.
domain
application
infrastructure
user
interface
DB
formAPI
File
converter adapter
つらい現実からドメインを守る💪
3つの盾
👉 form/request: 複雑なバリデーションルールから守る
👉 converter: 複雑なIF仕様から守る
👉 adapter: 物理データ構造から守る
💪 💪 💪
41 © BIGLOBE Inc.
domain
application
infrastructure
user
interface
DB
formAPI
File
converter adapter
つらい現実からドメインを守る💪 まとめ
3つの盾
👉 form/Request: 複雑なバリデーションルールから守る
👉 converter: 複雑なIF仕様から守る
👉 adapter: 物理データ構造から守る
💪 💪 💪
42 © BIGLOBE Inc.
こうしてドメインは守られた…☆
43 © BIGLOBE Inc.
ドメインに愛をこめて!
業務ロジックで充実&外部要因から守る!
44 © BIGLOBE Inc.
まとめ
これまでの取り組みの一部を紹介しました。
5年を経た失敗と成功をまとめましたが、
これは『今のところ』の結果です。
明日にはまたより良い成功が見つかるかもしれません。
社内ではいろんなチームが日々、試行錯誤しています。
ビッグローブの失敗と成功はまだまだ続いていきます。
一緒にDDDやっていきましょう 💪
BIGLOBE Internal Use Only

Mais conteúdo relacionado

Mais procurados

ドメイン駆動設計入門
ドメイン駆動設計入門ドメイン駆動設計入門
ドメイン駆動設計入門増田 亨
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意Yoshitaka Kawashima
 
オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門増田 亨
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ増田 亨
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)Takuto Wada
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
ドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解するドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解する増田 亨
 
強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話Yoshitaka Kawashima
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説増田 亨
 
DDDモデリング勉強会 #6
DDDモデリング勉強会 #6DDDモデリング勉強会 #6
DDDモデリング勉強会 #6株式会社Jurabi
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ増田 亨
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門増田 亨
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Masahito Zembutsu
 
webエンジニアのためのはじめてのredis
webエンジニアのためのはじめてのrediswebエンジニアのためのはじめてのredis
webエンジニアのためのはじめてのredisnasa9084
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)Yoshitaka Kawashima
 
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルドBuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルドAkihiro Suda
 

Mais procurados (20)

ドメイン駆動設計入門
ドメイン駆動設計入門ドメイン駆動設計入門
ドメイン駆動設計入門
 
イミュータブルデータモデルの極意
イミュータブルデータモデルの極意イミュータブルデータモデルの極意
イミュータブルデータモデルの極意
 
オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
ドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解するドメイン駆動設計 基本を理解する
ドメイン駆動設計 基本を理解する
 
強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話強いて言えば「集約どう実装するのかな、を考える」な話
強いて言えば「集約どう実装するのかな、を考える」な話
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説
 
DDDモデリング勉強会 #6
DDDモデリング勉強会 #6DDDモデリング勉強会 #6
DDDモデリング勉強会 #6
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
 
ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門ドメイン駆動設計 本格入門
ドメイン駆動設計 本格入門
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編
 
webエンジニアのためのはじめてのredis
webエンジニアのためのはじめてのrediswebエンジニアのためのはじめてのredis
webエンジニアのためのはじめてのredis
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)イミュータブルデータモデル(世代編)
イミュータブルデータモデル(世代編)
 
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルドBuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルド
 

Semelhante a ドメイン駆動設計 失敗したことと成功したこと

DDDモデリングハンズオン - レガシーをぶっつぶせ
DDDモデリングハンズオン - レガシーをぶっつぶせDDDモデリングハンズオン - レガシーをぶっつぶせ
DDDモデリングハンズオン - レガシーをぶっつぶせBIGLOBE Inc.
 
フォームクリエイター
フォームクリエイターフォームクリエイター
フォームクリエイターTomohiko Tasato
 
「モダンPerl入門」の入門
「モダンPerl入門」の入門「モダンPerl入門」の入門
「モダンPerl入門」の入門Songhee Han
 
進化するオープンソース・エンタープライズCMSがWeb戦略を変える
進化するオープンソース・エンタープライズCMSがWeb戦略を変える進化するオープンソース・エンタープライズCMSがWeb戦略を変える
進化するオープンソース・エンタープライズCMSがWeb戦略を変えるHishikawa Takuro
 
DDD Alliance レガシーなコードにドメイン駆動設計で立ち向かった5年間の軌跡
DDD Alliance レガシーなコードにドメイン駆動設計で立ち向かった5年間の軌跡DDD Alliance レガシーなコードにドメイン駆動設計で立ち向かった5年間の軌跡
DDD Alliance レガシーなコードにドメイン駆動設計で立ち向かった5年間の軌跡BIGLOBE Inc.
 
[AWSマイスターシリーズ] AWS Elastic Beanstalk
[AWSマイスターシリーズ] AWS Elastic Beanstalk[AWSマイスターシリーズ] AWS Elastic Beanstalk
[AWSマイスターシリーズ] AWS Elastic BeanstalkAmazon Web Services Japan
 
AZAREA-Cluster (Hadoop Conference Japan 2013 Winter Demo Image)
AZAREA-Cluster (Hadoop Conference Japan 2013 Winter Demo Image) AZAREA-Cluster (Hadoop Conference Japan 2013 Winter Demo Image)
AZAREA-Cluster (Hadoop Conference Japan 2013 Winter Demo Image) AzareaCluster
 
The story of forguncy ~インストール型ソフトウェアで実践するリーンスタートアップ~
The story of forguncy ~インストール型ソフトウェアで実践するリーンスタートアップ~The story of forguncy ~インストール型ソフトウェアで実践するリーンスタートアップ~
The story of forguncy ~インストール型ソフトウェアで実践するリーンスタートアップ~フォーガンシー
 
Webワークフローシステム R@bitFlow
Webワークフローシステム R@bitFlowWebワークフローシステム R@bitFlow
Webワークフローシステム R@bitFlowRicoh IT Solutions
 
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座DIVE INTO CODE Corp.
 
Collaboration Today Japan
Collaboration Today JapanCollaboration Today Japan
Collaboration Today JapanAtsushi Sato
 
Dangerでpull requestレビューの指摘事項を減らす
Dangerでpull requestレビューの指摘事項を減らすDangerでpull requestレビューの指摘事項を減らす
Dangerでpull requestレビューの指摘事項を減らすShunsuke Maeda
 
経営を支えるIT部門実現の記録2005
経営を支えるIT部門実現の記録2005経営を支えるIT部門実現の記録2005
経営を支えるIT部門実現の記録2005Makoto Shimizu
 
GitHub へのユーザー登録と既存のプロジェクトの検索
GitHub へのユーザー登録と既存のプロジェクトの検索GitHub へのユーザー登録と既存のプロジェクトの検索
GitHub へのユーザー登録と既存のプロジェクトの検索Hiroaki Komine
 
CodelessDevelop using iPaas
CodelessDevelop using iPaasCodelessDevelop using iPaas
CodelessDevelop using iPaasTomoyuki Obi
 
CodeIgniter 〜 2008年大躍進のPHPフレームワーク
CodeIgniter 〜 2008年大躍進のPHPフレームワークCodeIgniter 〜 2008年大躍進のPHPフレームワーク
CodeIgniter 〜 2008年大躍進のPHPフレームワークkenjis
 
20190212 apex demo
20190212 apex demo20190212 apex demo
20190212 apex demoutatu
 
AWS における Microservices Architecture と DevOps を推進する組織と人とツール
AWS における Microservices Architecture と DevOps を推進する組織と人とツールAWS における Microservices Architecture と DevOps を推進する組織と人とツール
AWS における Microservices Architecture と DevOps を推進する組織と人とツールAmazon Web Services Japan
 

Semelhante a ドメイン駆動設計 失敗したことと成功したこと (20)

DDDモデリングハンズオン - レガシーをぶっつぶせ
DDDモデリングハンズオン - レガシーをぶっつぶせDDDモデリングハンズオン - レガシーをぶっつぶせ
DDDモデリングハンズオン - レガシーをぶっつぶせ
 
フォームクリエイター
フォームクリエイターフォームクリエイター
フォームクリエイター
 
「モダンPerl入門」の入門
「モダンPerl入門」の入門「モダンPerl入門」の入門
「モダンPerl入門」の入門
 
進化するオープンソース・エンタープライズCMSがWeb戦略を変える
進化するオープンソース・エンタープライズCMSがWeb戦略を変える進化するオープンソース・エンタープライズCMSがWeb戦略を変える
進化するオープンソース・エンタープライズCMSがWeb戦略を変える
 
DDD Alliance レガシーなコードにドメイン駆動設計で立ち向かった5年間の軌跡
DDD Alliance レガシーなコードにドメイン駆動設計で立ち向かった5年間の軌跡DDD Alliance レガシーなコードにドメイン駆動設計で立ち向かった5年間の軌跡
DDD Alliance レガシーなコードにドメイン駆動設計で立ち向かった5年間の軌跡
 
20111212勉強会資料
20111212勉強会資料20111212勉強会資料
20111212勉強会資料
 
Force.com開発基礎
Force.com開発基礎Force.com開発基礎
Force.com開発基礎
 
[AWSマイスターシリーズ] AWS Elastic Beanstalk
[AWSマイスターシリーズ] AWS Elastic Beanstalk[AWSマイスターシリーズ] AWS Elastic Beanstalk
[AWSマイスターシリーズ] AWS Elastic Beanstalk
 
AZAREA-Cluster (Hadoop Conference Japan 2013 Winter Demo Image)
AZAREA-Cluster (Hadoop Conference Japan 2013 Winter Demo Image) AZAREA-Cluster (Hadoop Conference Japan 2013 Winter Demo Image)
AZAREA-Cluster (Hadoop Conference Japan 2013 Winter Demo Image)
 
The story of forguncy ~インストール型ソフトウェアで実践するリーンスタートアップ~
The story of forguncy ~インストール型ソフトウェアで実践するリーンスタートアップ~The story of forguncy ~インストール型ソフトウェアで実践するリーンスタートアップ~
The story of forguncy ~インストール型ソフトウェアで実践するリーンスタートアップ~
 
Webワークフローシステム R@bitFlow
Webワークフローシステム R@bitFlowWebワークフローシステム R@bitFlow
Webワークフローシステム R@bitFlow
 
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座アイデアを形にする  ③3時間でアプリ公開!ゼロからのプログラミング講座
アイデアを形にする ③3時間でアプリ公開!ゼロからのプログラミング講座
 
Collaboration Today Japan
Collaboration Today JapanCollaboration Today Japan
Collaboration Today Japan
 
Dangerでpull requestレビューの指摘事項を減らす
Dangerでpull requestレビューの指摘事項を減らすDangerでpull requestレビューの指摘事項を減らす
Dangerでpull requestレビューの指摘事項を減らす
 
経営を支えるIT部門実現の記録2005
経営を支えるIT部門実現の記録2005経営を支えるIT部門実現の記録2005
経営を支えるIT部門実現の記録2005
 
GitHub へのユーザー登録と既存のプロジェクトの検索
GitHub へのユーザー登録と既存のプロジェクトの検索GitHub へのユーザー登録と既存のプロジェクトの検索
GitHub へのユーザー登録と既存のプロジェクトの検索
 
CodelessDevelop using iPaas
CodelessDevelop using iPaasCodelessDevelop using iPaas
CodelessDevelop using iPaas
 
CodeIgniter 〜 2008年大躍進のPHPフレームワーク
CodeIgniter 〜 2008年大躍進のPHPフレームワークCodeIgniter 〜 2008年大躍進のPHPフレームワーク
CodeIgniter 〜 2008年大躍進のPHPフレームワーク
 
20190212 apex demo
20190212 apex demo20190212 apex demo
20190212 apex demo
 
AWS における Microservices Architecture と DevOps を推進する組織と人とツール
AWS における Microservices Architecture と DevOps を推進する組織と人とツールAWS における Microservices Architecture と DevOps を推進する組織と人とツール
AWS における Microservices Architecture と DevOps を推進する組織と人とツール
 

ドメイン駆動設計 失敗したことと成功したこと

  • 2. 2 © BIGLOBE Inc. 自己紹介 小林 映里奈(こばやし えりな) • @eri_twin • 2015年度入社の4年目 所属、担当業務 • ITシステム本部 ビッグローブ光開発チーム • ビッグローブ光の業務システムの開発
  • 3. 3 © BIGLOBE Inc. 今日のテーマ 失敗したことと成功したこと
  • 4. 4 © BIGLOBE Inc. ドメイン駆動設計への愛をこめて!
  • 5. 5 © BIGLOBE Inc. agenda ◆ ドメイン欠乏症との戦い ~実践と結果~ ◆ つらい現実からドメインを守る 3つの盾 ・Form ・Converter ・Adapter
  • 6. 6 © BIGLOBE Inc. ドメイン欠乏症との戦い ~実践と結果~ 「ドメインにロジックを書く」を実現するための試行錯誤
  • 7. 7 © BIGLOBE Inc. ドメイン欠乏症 手続き型のイメージで、ドメイン以外にロジックを書いてしまう ↓アプリケーション層にロジックがある例
  • 8. 8 © BIGLOBE Inc. ドメイン欠乏症 ドメインが出てこない… 👉 業務ロジックなど、業務の関心事は ドメインに書こう! たとえば、 前提条件のチェックは業務ロジック。 他には?
  • 9. 9 © BIGLOBE Inc. なにをドメインに書くべきか Q. どこまでがドメイン(=業務ロジック)なのか 業務ロジックに該当しそうなもの、たとえば - 業務に関連するドメインを取得する - 各ドメインが業務の前提条件を満たしているかチェック - ドメインの状態を変更する - 変更された状態のドメインを永続化する etc…
  • 10. 10 © BIGLOBE Inc. なにをドメインに書くべきか Q. どこまでがドメイン(=業務ロジック)なのか 業務ロジックに該当しそうなもの、たとえば - 業務に関連するドメインを取得する - 各ドメインが業務の前提条件を満たしているかチェック - ドメインの状態を変更する - 変更された状態のドメインを永続化する etc… A. 関連ドメインの取得・チェック・状態変更までを ドメインで扱う業務とする
  • 11. 11 © BIGLOBE Inc. ドメインの責務はここ
  • 12. 12 © BIGLOBE Inc. ドメイン欠乏症対策 👉 関連ドメイン取得のためドメイン層でリポジトリのDI 👉 前提条件チェック、変更後のエンティティ返却がドメインの責務 ↓ドメイン層のOrderDateにロジックを委譲
  • 13. 13 © BIGLOBE Inc. ドメイン欠乏症対策 👉 業務ロジックをドメインに委譲 👉 if文がなくなって見通しが良くなった ↓アプリケーション層はシンプルに
  • 14. 14 © BIGLOBE Inc. ドメイン欠乏症対策 🙆 ドメイン層にビジネスロジックがまとまる 🙆 アプリケーション層の見通しを良くできた 🙅‍リポジトリへのアクセスが入るため副作用が多く、 ドメイン層のテストがつらい → モック化すればいいと思ってたけど、それも大変だった → 実際やってみると、ドメインに集めすぎた感がある どこまでを業務(ドメイン)とみなすか、考え直す
  • 15. 15 © BIGLOBE Inc. 続:なにをドメインに書くべきか Q. どこまでがドメイン(=業務ロジック)なのか 業務ロジックに該当しそうなもの、たとえば - 業務に関連するドメインを取得する - 各ドメインが業務の前提条件を満たしているかチェック - ドメインの状態を変更する - 変更された状態のドメインを永続化する etc… A. リポジトリへのアクセスはアプリケーション層へ チェック・状態変更までをドメインで扱う業務とする
  • 16. 16 © BIGLOBE Inc. 続:ドメインの責務はここ
  • 17. 17 © BIGLOBE Inc. ドメイン 👉 必要な情報を受け取り、 イベント = 永続化に必要な情報をまとめたクラス を作る 👉 ドメインの内部に閉じたロジックはドメインに書く
  • 18. 18 © BIGLOBE Inc. ドメインサービス 👉 ドメインサービス(ドメイン層) 👉 ドメインサービスは業務の単位で分けている。 例では申込のユースケースなので、申込に関する業務ロジックを持つ
  • 19. 19 © BIGLOBE Inc. APサービス全体像 イベントを作る 永続化
  • 20. 20 © BIGLOBE Inc. ドメイン欠乏症対策2 🙆 サービス層の見通しが良い 🙆 リポジトリアクセス→イベント作成→永続化 の流れが わかりやすい 🙆‍副作用がないので、ドメイン層はテストしやすい これが今のところ良いかんじなので、継続中 Q.‍最初にすべてのエンティティを取得するのは冗長? 余計なリポジトリアクセスが多いのでは? A. そうでもない。 想定よりも無駄になるエンティティはかなり少なかった。
  • 21. 21 © BIGLOBE Inc. 中身のつまったドメインをつくろう!
  • 22. 22 © BIGLOBE Inc. つらい現実からドメインを守る 3つの盾 内部ではドメインを充実させていく一方、 外部からはさまざまな現実が攻めてきます
  • 23. 23 © BIGLOBE Inc. 現実の世界 domain service infrastructure 現実は想定外のさまざまなことが起きる お店の説明と違う! クーリングオフ したいです オーダー修正する時は XXのYYをZZZにして さらにAAAのBBを… このパターンの番号体系 が昨⽇日からS-­inしました K社 N社 ドメインの状態にはないけど、 契約開始後キャンセルが必要… ⼀一旦オーダーを取消 してやりなおします ええー!!
  • 24. 24 © BIGLOBE Inc. domain application infrastructure user interface DB formAPI File converter adapter つらい現実からドメインを守る💪 3つの盾 👉 form/request: 複雑なバリデーションルールから守る 👉 converter: 複雑なIF仕様から守る 👉 adapter: 物理データ構造から守る
  • 25. 25 © BIGLOBE Inc. domain application infrastructure user interface DB formAPI File converter adapter つらい現実からドメインを守る💪 3つの盾 👉 form/request: 複雑なバリデーションルールから守る 👉 converter: 複雑なIF仕様から守る 👉 adapter: 物理データ構造から守る
  • 26. 26 © BIGLOBE Inc. 複雑なバリデーションルールのつらみ 😭 APIが多すぎる! → 申込経路によってサービス仕様が違う → 経路Aと経路Bでバリデーションを分けたい → APIをユースケース単位で作成するので数が増える → 同じ商品の新規申込APIが50本とかあるような規模 😭 ドメイン層がバリデーションルールで汚れてしまう 🎈 form/requestとは バリデーションルールをユーザインターフェース層に出し APIや経路ごとにバリデーションを管理する!
  • 27. 27 © BIGLOBE Inc. Form 👉 @Patternにオブジェクトのバリデーションルールを書く 👉 ドメインオブジェクトに変換して返すgetterを用意 パラメータごとにXX(ドメイン名)Formを作る ex) ユーザIDを受け取るためのUserIdForm
  • 28. 28 © BIGLOBE Inc. Request 👉 先述のFormクラスをまとめたリクエストクラス API単位のリクエストパラメータを表現している 👉 API固有のパラメータの必須/非必須や相関チェックをここで管理する 👉 Formの値がnullだとオブジェクトをgetしたときに例外になるので nullの場合はバリデーションエラーにするアノテーションを作った (@ValueObjectNotEmpty)
  • 29. 29 © BIGLOBE Inc. API 👉 リクエストで受け取ったパラメータを バリデーション済みのオブジェクトとして取り出す
  • 30. 30 © BIGLOBE Inc. domain application infrastructure user interface DB formAPI File converter adapter つらい現実からドメインを守る💪 3つの盾 👉 form/request: 複雑なバリデーションルールから守る 👉 converter: 複雑なIF仕様から守る 👉 adapter: 物理データ構造から守る 💪 守った!
  • 31. 31 © BIGLOBE Inc. domain application infrastructure user interface DB formAPI File converter adapter つらい現実からドメインを守る💪 3つの盾 👉 form/request: 複雑なバリデーションルールから守る 👉 converter: 複雑なIF仕様から守る 👉 adapter: 物理データ構造から守る 💪
  • 32. 32 © BIGLOBE Inc. 複雑なIF仕様のつらみ 😭 大企業様から提供されるIF仕様書はむずかしい → 写し間違えて項目ずれるの怖い → 項目数が多いと確認も大変 😭 社内と社外では世界観が違う → ドメインモデルと異なる形のデータ群を求められる → せっかく作ったモデルはIF仕様に引っ張られたくない… 🎈 Converterとは 複雑なIF仕様をそのままコードに落とす! 外部都合のIFから自分たちのドメインモデルを守る!
  • 33. 33 © BIGLOBE Inc. Converter: 複雑なIF仕様から守る IF仕様書をそのままコードに落とす 👉 外部のドメインと自分たちのドメインの言葉を紐付ける このクラスのコードが言葉の差を埋める設計資料そのものになる 👉 どのエンティティのフィールドかひと目でわかる ex) v.会員()は会員エンティティにあるデータを使っている 👉 サンプルデータをそのまま期待値に使ったテストが書ける! ↑外部のドメイン ⾃自分たちのドメイン
  • 34. 34 © BIGLOBE Inc. Converter: 複雑なIF仕様から守る ドメインモデルの世界観を守る 👉 IFの契約者住所はアパート名を含むが、モデルは住所とアパート名が別 👉 converterで住所とアパート名を繋げたデータを作る 👉 モデルは変えず、IF仕様との世界観の差はconverterが吸収する
  • 35. 35 © BIGLOBE Inc. domain application infrastructure user interface DB formAPI File converter adapter つらい現実からドメインを守る💪 3つの盾 👉 form/request: 複雑なバリデーションルールから守る 👉 converter: 複雑なIF仕様から守る 👉 adapter: 物理データ構造から守る 💪 💪
  • 36. 36 © BIGLOBE Inc. domain application infrastructure user interface DB formAPI File converter adapter つらい現実からドメインを守る💪 3つの盾 👉 form/request: 複雑なバリデーションルールから守る 👉 converter: 複雑なIF仕様から守る 👉 adapter: 物理データ構造から守る 💪 💪
  • 37. 37 © BIGLOBE Inc. 物理データのつらみ 前提:O/RマッパーはMyBatisを使っている 😭 データをエンティティに変換するマッピングがつらい
  • 38. 38 © BIGLOBE Inc. 物理データのつらみ Q. Javaのクラス自動生成してくれるO/RM使わないの? A. 扱うデータ量が非常に多いので、チューニング必須。 SQLをカスタマイズしやすいO/RMを使いたい。 MyBatisのよいところ 👉 SQLを直に書ける(チューニングできる) (超大事) MyBatisのつらいところ 👉 xmlでマッピングを書くのが大変 👉 コンパイルエラーにならないので実行時エラーが出る 👉 エラーがわかりにくいので原因の調査に苦労する 🎈 Adapterとは よいところだけを活かす! MyBatisを使いながらマッピングはJavaで行う!
  • 39. 39 © BIGLOBE Inc. Adapter Javaの基本的なクラスでDBから値を取得する。 👉 VARCHER型はString, DATE型はLocalDate(LocalDateTime) 👉 値を取得する段階ではバリューオブジェクトへの変換処理はしない バリューオブジェクトへの変換ロジックはadapterに集める
  • 40. 40 © BIGLOBE Inc. domain application infrastructure user interface DB formAPI File converter adapter つらい現実からドメインを守る💪 3つの盾 👉 form/request: 複雑なバリデーションルールから守る 👉 converter: 複雑なIF仕様から守る 👉 adapter: 物理データ構造から守る 💪 💪 💪
  • 41. 41 © BIGLOBE Inc. domain application infrastructure user interface DB formAPI File converter adapter つらい現実からドメインを守る💪 まとめ 3つの盾 👉 form/Request: 複雑なバリデーションルールから守る 👉 converter: 複雑なIF仕様から守る 👉 adapter: 物理データ構造から守る 💪 💪 💪
  • 42. 42 © BIGLOBE Inc. こうしてドメインは守られた…☆
  • 43. 43 © BIGLOBE Inc. ドメインに愛をこめて! 業務ロジックで充実&外部要因から守る!
  • 44. 44 © BIGLOBE Inc. まとめ これまでの取り組みの一部を紹介しました。 5年を経た失敗と成功をまとめましたが、 これは『今のところ』の結果です。 明日にはまたより良い成功が見つかるかもしれません。 社内ではいろんなチームが日々、試行錯誤しています。 ビッグローブの失敗と成功はまだまだ続いていきます。 一緒にDDDやっていきましょう 💪