Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
ドメイン駆動設計による
サービス開発
DDD ALLIANCE!
ドメイン駆動設計をやってみた 6つの現場から
の報告
自己紹介
名前:大西 真央(@mmmmao0530)
組織としての役割:DDD布教活動
チームとしての役割:リードエンジニア
(技術リーダー)
最近の関心ごと:効果的なドメインモデルの作成
チームビルディング
概要
ビッグローブでDDDを導入して早2年。
この2年間、ISP事業における主要なサービスをDDDで開発してき
て、試行錯誤の連続でした。
今回は、試行錯誤の過程を経て生まれた、実際に実践している
・設計・実装の考え方(ドメインモデルやコード例...
アジェンダ
1. 導入
• Biglobe × DDD
2. チーム環境の考え方
• スクラム開発
• チームビルディング
3. 設計・実装の考え方
• アプリケーションコード
• DB設計
4. 失敗談
5. まとめ
導入
Biglobe × DDD
DDDの歴史と組織
DDD 適用サービスの歴史
2013年 2014年 2015年
Wi-Fi
スポット
LTE/3G
音声
Biglobe
電話
Biglobe光
MVNO支援
サービス
リニュー
アル
ドコモ光
LTE/3G
全部
新規
サービス
LTE/3G...
5チーム/30人規模で
DDD実践中!
全開発者の30%
100名規模で
DDDを実践できる
組織にしたい!
組織として大事にしていること
全開発者でDDDの価値を共有。
現状の課題分析と課題解決に向けての行動。
人材育成計画。
新たな技術にチャレンジ。
開発環境基盤の高度化もちゃんとやる。
DDDを
採用する
価値
開発現場の取り巻く環境
サービス
関心事が何
か?明確化
誰の関心事
なのか?
価値の最大化
開発現場の取り巻く環境
サービス
関心事が何
か?明確化
サービスを継続
することが前提
誰の関心事
なのか?
価値の最大化
開発現場の取り巻く環境
サービス
関心事が何
か?明確化
サービスを継続
することが前提
誰の関心事
なのか?
使われ続ける
変更し続ける
成長し続ける
価値の最大化
開発現場の取り巻く環境
サービス
関心事が何
か?明確化
サービスを継続
することが前提
誰の関心事
なのか?
使われ続ける
変更し続ける
成長し続ける
関わる人も
変わっていく
価値が
変わる可能性大
価値の最大化
開発現場の取り巻く環境
サービス
関心事が何
か?明確化
サービスを継続
することが前提
誰の関心事
なのか?
使われ続ける
変更し続ける
成長し続ける
関わる人も
変わっていく
価値が
変わる可能性大
価値の最大化
課題
独自言語だと
つぎはぎで機能強化
していくので
サービスの維持で
精一杯
機能強化に
莫大な費用がかかる
サービス終了までの
トータルコストの削減
が大事
DDDを採用する価値
トータル
コスト削減
DDDを採用する価値
トータル
コスト削減
変更コスト
を下げる
属人性を
下げる
DDDを採用する価値
トータル
コスト削減
変更コスト
を下げる
属人性を
下げる
業務を
コードで
表現
チーム環境の考え方
スクラム開発
スクラムの概要
DDD目線でのスクラム
立ち上げ
初期ドメイン
モデルなど
スプリント
ドメイン
モデル
1W~3W
1W
24H
コード
リリース
2M~3M
プロダクト
バックログ
スプリント
バックログ
プロ
ダクト
立ち上げ
初期ドメイ
ンモデル
業務
フロー図
ユースケース
フロー図
スケルトン
コード
DB設計
状態
遷移図
コンテキス
トマップ
①
②
③
④ ③
③
③
初期ドメイ
ンモデル
業務
フロー図
ユースケース
フロー図
スケルトン
コード
DB設計
状態
遷移図
コンテキス
トマップ
①
②
③
④ ③
③
③
ドメインモデルを
成長させる
例:ユースケースフロー図
アクター
処理の流れ
ユースケース単位に
どのエンティティが
何の業務をするの
か設計。
主にアプリケーショ
ン層の設計。
立ち上げ時の
心構え
開発初期は
わからない事
だらけ
開発初期は
わからない事
だらけ
方向付け
レベルの設計
に留める
コアドメインを議論することは
サービスを理解する第一歩
サービスの複雑性と
向き合う
スプリント
ドメイン
モデル
ユースケース
フロー図
コード
スプリント
バックログ
各メンバーがスプリントバックログに着手。
ドメインモデルとコードを結びつける
↓
モデルの持つ意図をコードに引き継ぎ
コードを通してモデルにフィードバック
設計者と実装者を分離しない
スプリント時の
心構え
コアドメインの設計・実装は
重点的に
プルリクエストの
WIPを活用して
効率的にレビューを!
WIP:Work In Progress
(作業中)の略。
スプリントごとに
ドメインモデルから
重要な概念を追加
不要な概念を削除
普段の会話の
ぎこちなさに敏感になる
書き言葉と
話し言葉が
ズレたら
警告サイン
初期のドメインモデルや実装では
重要と思わなかった問題が
見つかる可能性がある
見つけた問題を放置すると
いつか困ったことになる
ドメインモデルと実装を
改善するプロセスが大事
スクラム開発 まとめ
ドメインモデルは時間と共に進化。
立ち上げ時は方向付けレベルの設計。
スプリント内の設計活動が重要。
チーム環境の考え方
チームビルディング
SW開発における
チームビルディング
の必要性
SW開発はチームスポーツであり
技術的要因と同じだけ人的要因が
パフォーマンスに影響
チームメンバーが相乗効果を発揮
知識(要求)が絶えず変化するので
知識の共有が大事
DDDにおける
チームビルディング
の必要性
本の紹介
チーミング
素直に意見を言う 試みる 協働する 省察する
学習するための組織づくり
境界を越えて通じ合う 失敗から学ぶ 心理的安全を生み出す 学習するための骨組みを作る
学習しながら実行する
診断する デザインする 行動する 省察する
学習しな...
チーミング
素直に意見を言う 試みる 協働する 省察する
学習するための組織づくり
境界を越えて通じ合う 失敗から学ぶ 心理的安全を生み出す 学習するための骨組みを作る
学習しながら実行する
診断する デザインする 行動する 省察する
学習しな...
効率を追求しながら実行する 学習しながら実行する
リーダーは答えを持っている リーダーは方向性を定める
決まったプロセスが導入される 出発点として意図的に仮の作業プロ
セスが設けられる
変わることは大変な労力を伴う仕事
だと考えられる
絶えず少...
効率を追求しながら実行する 学習しながら実行する
リーダーは答えを持っている リーダーは方向性を定める
決まったプロセスが導入される 出発点として意図的に仮の作業プロ
セスが設けられる
変わることは大変な労力を伴う仕事
だと考えられる
絶えず少...
DDDに関連する
チームビルディング
の内容
1つ目
全員で設計
メンバー全員が考える場を作る。
メンバーの意見を引き出す。
メンバー間のギャップをなくす。
ファシリテーション重要
メンバー全員が
同じ地図(ドメインモデル)を
理解するため
設計の目的と効果をメンバー全員が
理解して実装するため
熟練者のノウハウを
経験が浅いメンバーに
伝授するため
全員で設計する目的
2つ目
モデリング済みの部分も
積極的にモデリング
大規模な機能強化時
プランニング時
バックログの着手時
コードレビュー時
朝会後に
行き詰った時
ホワイトボードがあれば
いつでもモデリングできる
経験が浅いメンバーは
モデリングする機会を増やす
ことが成長につながる
新規加入メンバーは
ドメインを理解する
チャンス
モデリングは
メンバー自身に実施させる
チーム
ビルディング
の結果
チームの設計力が強化
変更コスト/属人性
が下がる
DDDを採用する価値
トータル
コスト削減
変更コスト
を下げる
属人性を
下げる
業務を
コードで
表現
DDDを採用する価値
につながる。
チームビルディング まとめ
DDDはチームビルディングが必須。
全員で設計することが大事。
既存部分も積極的にモデリングするこ
とが大事。
設計・実装の考え方
アプリケーションコード
組織で行った
DDD勉強会の
コードを紹介
動作環境
言語 : Java8
フレームワーク : SpringFramework
O/Rマッピング : MyBatis
DB : Oracle(ローカルはH2)
ビルドツール : Gradle
ユース
ケース
コンテキストマップ
ドメイン
モデル
入会仕様
入会可能条件
20歳以上である。
利用可能なクレジットカードを保持している。
接続コースは「ベーシック」または「ニコニコ」で申
し込む。
入会の際、会員登録情報として申込者の個人情報を必
要とする。
レイヤー構造
ドメイン層
API層 アプリケー
ション層
インフラスト
ラクチャ層
ドメイン層を
独立させる
ドメイン層に
依存させる
ここからコードで
アプリケーション層
入会サービス
アプリケーション層
入会審査サービス
ドメイン層
会員エンティティ
ドメイン層
リアルタイム審査
データソース層
会員リポジトリ
データアクセス層
会員リポジトリの
Mapper
設計・実装の考え方
DB設計
イミュータブル
データモデル
業務が発生すると、
業務履歴をひたすら記録
(insert)
これだけ
とある業務に対する
変更業務も
当たり前のように記録
(insert)
変更業務で
Updateすると
記録の改ざん
これは、極論です(笑)
業務を中心に捉えると
業務ごとにデータが
残る方が自然
現実は
Insertオンリーな
DB設計は難しい
テーブルの種類
Eventテーブル
業務が発生するとひたすらinsertしていく
テーブル。
Stateテーブル
業務が発生すると必要に応じてupdateし
ていくテーブル。
ステータスなど最新の情報を管理。
Eventテーブルが中心。
Stateテーブルは補助。
Stateテーブルの使いどころ
パフォーマンス改善が図れる場合。
DB側で業務イベントの発生ルールを完璧
にコントロールしたい場合。(詳細は後
程。)
Stateテーブルは
データアクセス層の
関心ごとで利用
イミュータブル
データモデルを徹底すると
副次効果として
NULL項目が減る!
具体的な話
DDD勉強会の
DB設計
biglobeID
入会日
biglobeID(FK)
退会日
入会 退会
会員に関連するテーブル
abc12345
2015/10/10
abc12345
2016/10/10
退会イベント入会イベント
入会 退会
業務が発生すると、
関連するテーブルに業務履歴を記録(insert)
biglobeID
入会日
退会日
会員
ミュータブル
データモデル
だけ
abc12345
2015/10/10
null
abc12345
2015/10/10
2016/10/10
会員 会員
update
退会イベント入会イベント
もう少し
難しく
契約
エンティティ
に対する
DB設計
の場合
申込中
契約中
解約予
約中
解約済
申込
キャンセル
申込ID
申込ID(FK)
申込
契約
申込ID(FK)
キャンセル
解約ID
申込ID(FK)
解約日
解約
解約ID(FK)
解約キャンセル
申込ID
申込ID(FK)
申込
契約
申込ID(FK)
キャンセル
解約ID
申込ID(FK)
解約日
解約
解約ID(FK)
解約キャンセル各テーブルの外部キーにより
業務イベントの流れをコントロール
これに
Stateテーブルを
足すなら
申込ID
申込ID(FK)
申込
契約
申込ID(FK)
キャンセル
解約ID
申込ID(FK)
解約
解約ID(FK)
解約キャンセル
申込ID(FK)
ステータス
申込ID
申込ID(FK)
申込
契約
申込ID(FK)
キャンセル
解約ID
申込ID(FK)
解約
解約ID(FK)
解約キャンセル
申込ID(FK)
ステータス
契約とキャンセルは排他な関係。
契約とキャンセルが同時に発生した場合、アプ
リケーションコードとEventテーブルだけで、
この制約を実現できない。
Stateテーブル更新時のWhere句で
ステータスも条件(ステータス=申込中)に
入れることにより、この制約を維持できる。
申込ID
申込ID(FK)
申込
契約
申込ID(FK)
キャンセル
解約ID
申込ID(FK)
解約
解約ID(FK)
解約キャンセル
申込ID(FK)
ステータス
解約キャンセルするユーザが少ない
と判断して、Stateテーブルは導入しない...
失敗談
ドメインモデル関連
ドメインモデルが古い
ドメイン層関連
Policyクラスの乱立
データアクセス層関連
Repositoryのsaveメソッド
他集約のRepositoryを操作
SQLに業務ロジックが混在
失敗談
ドメインモデルが古い
ドメインモデルが古い
内容
日々変化するドメインモデルが最新化されない。
問題点
値オブジェクトを全部管理していたので、更新が追い付かない。
最新のドメインモデルが把握できない。
対策
最初に作成するドメインモデルとKeepするド...
ドメインモデルが古い
最初に作成する
ドメインモデル
ドメインモデルが古い
Keepする
ドメインモデル
失敗談
Policyクラスの乱立
Policyクラスの乱立
内容
業務チェックのために、ドメイン層にPolicyクラスを用意。
問題点
エンティティから業務ロジックが抜けていく(エンティ
ティ貧血症)。
対策
基本的には、エンティティに業務チェックを記述。
明示的...
Policyクラスの乱立
Policyパッケージを
作った時点で負け
失敗談
Repositoryのsaveメソッド
Repositoryのsaveメソッド
内容
永続化のメソッドをsaveメソッドのみで対応。
問題点
テーブル構成がドメイン層に浸食。
saveメソッドでどのテーブルが登録・更新されるか不明。
saveメソッドをメンテナンスできるメ...
失敗談
他集約のRepositoryを操作
他集約のRepositoryを操作
内容
他集約のRepositoryをデータアクセス層で操作。
問題点
アプリケーション層のコードだけでは関連する集約が把握
できず、全てのコードを読む必要がある。
影響範囲の特定に時間がかかる。ミス...
失敗談
SQLに業務ロジックが混在
SQLに業務ロジックが混在
内容
SelectのWhere句に業務ロジックが記述。
問題点
業務ロジックがドメイン層から流出。
いつかの仕様変更でバグの温床に。
対策
可能な限り業務ロジックはドメイン層に集約。
検索条件は主キーのみにして
ステータスの絞り込み条件はド
メイン層で記述
まとめ
DDD本と現場での実践を
行ったり来たりして
理解を深めていくことが重要
サービスが存在する限り
変化し続け
成長し続け
価値を届け続ける
ソフトウェアを作ることが重要
ご静聴
ありがとうございました。
20151110 ドメイン駆動設計によるサービス開発
Upcoming SlideShare
Loading in …5
×

20151110 ドメイン駆動設計によるサービス開発

9,081 views

Published on

ビッグローブでDDDを導入して早2年。
この2年間、ISP事業における主要なサービスをDDDで開発してきて、試行錯誤の連続でした。
今回は、試行錯誤の過程を経て生まれた、実際に実践している
 ・設計・実装の考え方(ドメインモデルやコード例やDB設計など)
 ・チーム環境の考え方(開発プロセスやチームビルディングなど)
の2つを軸に現場でのリアルな体験を紹介します。
また、最後に、試行錯誤における失敗談も紹介します。

Published in: Software
  • Be the first to comment

20151110 ドメイン駆動設計によるサービス開発

  1. 1. ドメイン駆動設計による サービス開発 DDD ALLIANCE! ドメイン駆動設計をやってみた 6つの現場から の報告
  2. 2. 自己紹介 名前:大西 真央(@mmmmao0530) 組織としての役割:DDD布教活動 チームとしての役割:リードエンジニア (技術リーダー) 最近の関心ごと:効果的なドメインモデルの作成 チームビルディング
  3. 3. 概要 ビッグローブでDDDを導入して早2年。 この2年間、ISP事業における主要なサービスをDDDで開発してき て、試行錯誤の連続でした。 今回は、試行錯誤の過程を経て生まれた、実際に実践している ・設計・実装の考え方(ドメインモデルやコード例やDB設計な ど) ・チーム環境の考え方(開発プロセスやチームビルディングな ど) の2つを軸に現場でのリアルな体験を紹介します。 また、最後に、試行錯誤における失敗談も紹介します。
  4. 4. アジェンダ 1. 導入 • Biglobe × DDD 2. チーム環境の考え方 • スクラム開発 • チームビルディング 3. 設計・実装の考え方 • アプリケーションコード • DB設計 4. 失敗談 5. まとめ
  5. 5. 導入 Biglobe × DDD
  6. 6. DDDの歴史と組織
  7. 7. DDD 適用サービスの歴史 2013年 2014年 2015年 Wi-Fi スポット LTE/3G 音声 Biglobe 電話 Biglobe光 MVNO支援 サービス リニュー アル ドコモ光 LTE/3G 全部 新規 サービス LTE/3G 帯域制御 NINJA SIM ※初回S-inのみ記載。各サービスは現在も開発中。
  8. 8. 5チーム/30人規模で DDD実践中! 全開発者の30%
  9. 9. 100名規模で DDDを実践できる 組織にしたい!
  10. 10. 組織として大事にしていること 全開発者でDDDの価値を共有。 現状の課題分析と課題解決に向けての行動。 人材育成計画。 新たな技術にチャレンジ。 開発環境基盤の高度化もちゃんとやる。
  11. 11. DDDを 採用する 価値
  12. 12. 開発現場の取り巻く環境 サービス 関心事が何 か?明確化 誰の関心事 なのか? 価値の最大化
  13. 13. 開発現場の取り巻く環境 サービス 関心事が何 か?明確化 サービスを継続 することが前提 誰の関心事 なのか? 価値の最大化
  14. 14. 開発現場の取り巻く環境 サービス 関心事が何 か?明確化 サービスを継続 することが前提 誰の関心事 なのか? 使われ続ける 変更し続ける 成長し続ける 価値の最大化
  15. 15. 開発現場の取り巻く環境 サービス 関心事が何 か?明確化 サービスを継続 することが前提 誰の関心事 なのか? 使われ続ける 変更し続ける 成長し続ける 関わる人も 変わっていく 価値が 変わる可能性大 価値の最大化
  16. 16. 開発現場の取り巻く環境 サービス 関心事が何 か?明確化 サービスを継続 することが前提 誰の関心事 なのか? 使われ続ける 変更し続ける 成長し続ける 関わる人も 変わっていく 価値が 変わる可能性大 価値の最大化 課題
  17. 17. 独自言語だと つぎはぎで機能強化 していくので サービスの維持で 精一杯
  18. 18. 機能強化に 莫大な費用がかかる
  19. 19. サービス終了までの トータルコストの削減 が大事
  20. 20. DDDを採用する価値 トータル コスト削減
  21. 21. DDDを採用する価値 トータル コスト削減 変更コスト を下げる 属人性を 下げる
  22. 22. DDDを採用する価値 トータル コスト削減 変更コスト を下げる 属人性を 下げる 業務を コードで 表現
  23. 23. チーム環境の考え方 スクラム開発
  24. 24. スクラムの概要
  25. 25. DDD目線でのスクラム 立ち上げ 初期ドメイン モデルなど スプリント ドメイン モデル 1W~3W 1W 24H コード リリース 2M~3M プロダクト バックログ スプリント バックログ プロ ダクト
  26. 26. 立ち上げ
  27. 27. 初期ドメイ ンモデル 業務 フロー図 ユースケース フロー図 スケルトン コード DB設計 状態 遷移図 コンテキス トマップ ① ② ③ ④ ③ ③ ③
  28. 28. 初期ドメイ ンモデル 業務 フロー図 ユースケース フロー図 スケルトン コード DB設計 状態 遷移図 コンテキス トマップ ① ② ③ ④ ③ ③ ③ ドメインモデルを 成長させる
  29. 29. 例:ユースケースフロー図 アクター 処理の流れ ユースケース単位に どのエンティティが 何の業務をするの か設計。 主にアプリケーショ ン層の設計。
  30. 30. 立ち上げ時の 心構え
  31. 31. 開発初期は わからない事 だらけ
  32. 32. 開発初期は わからない事 だらけ 方向付け レベルの設計 に留める
  33. 33. コアドメインを議論することは サービスを理解する第一歩
  34. 34. サービスの複雑性と 向き合う
  35. 35. スプリント
  36. 36. ドメイン モデル ユースケース フロー図 コード スプリント バックログ 各メンバーがスプリントバックログに着手。
  37. 37. ドメインモデルとコードを結びつける ↓ モデルの持つ意図をコードに引き継ぎ コードを通してモデルにフィードバック
  38. 38. 設計者と実装者を分離しない
  39. 39. スプリント時の 心構え
  40. 40. コアドメインの設計・実装は 重点的に
  41. 41. プルリクエストの WIPを活用して 効率的にレビューを! WIP:Work In Progress (作業中)の略。
  42. 42. スプリントごとに ドメインモデルから 重要な概念を追加 不要な概念を削除
  43. 43. 普段の会話の ぎこちなさに敏感になる
  44. 44. 書き言葉と 話し言葉が ズレたら 警告サイン
  45. 45. 初期のドメインモデルや実装では 重要と思わなかった問題が 見つかる可能性がある
  46. 46. 見つけた問題を放置すると いつか困ったことになる
  47. 47. ドメインモデルと実装を 改善するプロセスが大事
  48. 48. スクラム開発 まとめ ドメインモデルは時間と共に進化。 立ち上げ時は方向付けレベルの設計。 スプリント内の設計活動が重要。
  49. 49. チーム環境の考え方 チームビルディング
  50. 50. SW開発における チームビルディング の必要性
  51. 51. SW開発はチームスポーツであり 技術的要因と同じだけ人的要因が パフォーマンスに影響
  52. 52. チームメンバーが相乗効果を発揮
  53. 53. 知識(要求)が絶えず変化するので 知識の共有が大事
  54. 54. DDDにおける チームビルディング の必要性
  55. 55. 本の紹介
  56. 56. チーミング 素直に意見を言う 試みる 協働する 省察する 学習するための組織づくり 境界を越えて通じ合う 失敗から学ぶ 心理的安全を生み出す 学習するための骨組みを作る 学習しながら実行する 診断する デザインする 行動する 省察する 学習しながら実行するための土台
  57. 57. チーミング 素直に意見を言う 試みる 協働する 省察する 学習するための組織づくり 境界を越えて通じ合う 失敗から学ぶ 心理的安全を生み出す 学習するための骨組みを作る 学習しながら実行する 診断する デザインする 行動する 省察する 学習しながら実行するための土台 DDDで必須の考え方
  58. 58. 効率を追求しながら実行する 学習しながら実行する リーダーは答えを持っている リーダーは方向性を定める 決まったプロセスが導入される 出発点として意図的に仮の作業プロ セスが設けられる 変わることは大変な労力を伴う仕事 だと考えられる 絶えず少しずつ変化することが日常 的になる 一方通行のフィードバックがなされ る 双方向のフィードバックがなされる 社員の判断は阻止される 社員の判断は不可欠である 上司を恐れるのは普通のことである 不安があると試みや分析や問題解決 が妨げられる 目標:今日にも利益を勝ち取ること 目標:長期的な価値を生み出すこと
  59. 59. 効率を追求しながら実行する 学習しながら実行する リーダーは答えを持っている リーダーは方向性を定める 決まったプロセスが導入される 出発点として意図的に仮の作業プロ セスが設けられる 変わることは大変な労力を伴う仕事 だと考えられる 絶えず少しずつ変化することが日常 的になる 一方通行のフィードバックがなされ る 双方向のフィードバックがなされる 社員の判断は阻止される 社員の判断は不可欠である 上司を恐れるのは普通のことである 不安があると試みや分析や問題解決 が妨げられる 目標:今日にも利益を勝ち取ること 目標:長期的な価値を生み出すこと
  60. 60. DDDに関連する チームビルディング の内容
  61. 61. 1つ目
  62. 62. 全員で設計
  63. 63. メンバー全員が考える場を作る。 メンバーの意見を引き出す。 メンバー間のギャップをなくす。 ファシリテーション重要
  64. 64. メンバー全員が 同じ地図(ドメインモデル)を 理解するため
  65. 65. 設計の目的と効果をメンバー全員が 理解して実装するため
  66. 66. 熟練者のノウハウを 経験が浅いメンバーに 伝授するため 全員で設計する目的
  67. 67. 2つ目
  68. 68. モデリング済みの部分も 積極的にモデリング
  69. 69. 大規模な機能強化時 プランニング時 バックログの着手時 コードレビュー時 朝会後に 行き詰った時 ホワイトボードがあれば いつでもモデリングできる
  70. 70. 経験が浅いメンバーは モデリングする機会を増やす ことが成長につながる
  71. 71. 新規加入メンバーは ドメインを理解する チャンス
  72. 72. モデリングは メンバー自身に実施させる
  73. 73. チーム ビルディング の結果
  74. 74. チームの設計力が強化
  75. 75. 変更コスト/属人性 が下がる
  76. 76. DDDを採用する価値 トータル コスト削減 変更コスト を下げる 属人性を 下げる 業務を コードで 表現 DDDを採用する価値 につながる。
  77. 77. チームビルディング まとめ DDDはチームビルディングが必須。 全員で設計することが大事。 既存部分も積極的にモデリングするこ とが大事。
  78. 78. 設計・実装の考え方 アプリケーションコード
  79. 79. 組織で行った DDD勉強会の コードを紹介
  80. 80. 動作環境 言語 : Java8 フレームワーク : SpringFramework O/Rマッピング : MyBatis DB : Oracle(ローカルはH2) ビルドツール : Gradle
  81. 81. ユース ケース
  82. 82. コンテキストマップ
  83. 83. ドメイン モデル
  84. 84. 入会仕様 入会可能条件 20歳以上である。 利用可能なクレジットカードを保持している。 接続コースは「ベーシック」または「ニコニコ」で申 し込む。 入会の際、会員登録情報として申込者の個人情報を必 要とする。
  85. 85. レイヤー構造 ドメイン層 API層 アプリケー ション層 インフラスト ラクチャ層 ドメイン層を 独立させる ドメイン層に 依存させる
  86. 86. ここからコードで
  87. 87. アプリケーション層 入会サービス
  88. 88. アプリケーション層 入会審査サービス
  89. 89. ドメイン層 会員エンティティ
  90. 90. ドメイン層 リアルタイム審査
  91. 91. データソース層 会員リポジトリ
  92. 92. データアクセス層 会員リポジトリの Mapper
  93. 93. 設計・実装の考え方 DB設計
  94. 94. イミュータブル データモデル
  95. 95. 業務が発生すると、 業務履歴をひたすら記録 (insert) これだけ
  96. 96. とある業務に対する 変更業務も 当たり前のように記録 (insert)
  97. 97. 変更業務で Updateすると 記録の改ざん これは、極論です(笑)
  98. 98. 業務を中心に捉えると 業務ごとにデータが 残る方が自然
  99. 99. 現実は Insertオンリーな DB設計は難しい
  100. 100. テーブルの種類 Eventテーブル 業務が発生するとひたすらinsertしていく テーブル。 Stateテーブル 業務が発生すると必要に応じてupdateし ていくテーブル。 ステータスなど最新の情報を管理。
  101. 101. Eventテーブルが中心。 Stateテーブルは補助。
  102. 102. Stateテーブルの使いどころ パフォーマンス改善が図れる場合。 DB側で業務イベントの発生ルールを完璧 にコントロールしたい場合。(詳細は後 程。)
  103. 103. Stateテーブルは データアクセス層の 関心ごとで利用
  104. 104. イミュータブル データモデルを徹底すると 副次効果として NULL項目が減る!
  105. 105. 具体的な話
  106. 106. DDD勉強会の DB設計
  107. 107. biglobeID 入会日 biglobeID(FK) 退会日 入会 退会 会員に関連するテーブル
  108. 108. abc12345 2015/10/10 abc12345 2016/10/10 退会イベント入会イベント 入会 退会 業務が発生すると、 関連するテーブルに業務履歴を記録(insert)
  109. 109. biglobeID 入会日 退会日 会員 ミュータブル データモデル だけ
  110. 110. abc12345 2015/10/10 null abc12345 2015/10/10 2016/10/10 会員 会員 update 退会イベント入会イベント
  111. 111. もう少し 難しく
  112. 112. 契約 エンティティ に対する DB設計 の場合 申込中 契約中 解約予 約中 解約済 申込 キャンセル
  113. 113. 申込ID 申込ID(FK) 申込 契約 申込ID(FK) キャンセル 解約ID 申込ID(FK) 解約日 解約 解約ID(FK) 解約キャンセル
  114. 114. 申込ID 申込ID(FK) 申込 契約 申込ID(FK) キャンセル 解約ID 申込ID(FK) 解約日 解約 解約ID(FK) 解約キャンセル各テーブルの外部キーにより 業務イベントの流れをコントロール
  115. 115. これに Stateテーブルを 足すなら
  116. 116. 申込ID 申込ID(FK) 申込 契約 申込ID(FK) キャンセル 解約ID 申込ID(FK) 解約 解約ID(FK) 解約キャンセル 申込ID(FK) ステータス
  117. 117. 申込ID 申込ID(FK) 申込 契約 申込ID(FK) キャンセル 解約ID 申込ID(FK) 解約 解約ID(FK) 解約キャンセル 申込ID(FK) ステータス 契約とキャンセルは排他な関係。
  118. 118. 契約とキャンセルが同時に発生した場合、アプ リケーションコードとEventテーブルだけで、 この制約を実現できない。 Stateテーブル更新時のWhere句で ステータスも条件(ステータス=申込中)に 入れることにより、この制約を維持できる。
  119. 119. 申込ID 申込ID(FK) 申込 契約 申込ID(FK) キャンセル 解約ID 申込ID(FK) 解約 解約ID(FK) 解約キャンセル 申込ID(FK) ステータス 解約キャンセルするユーザが少ない と判断して、Stateテーブルは導入しない。 最新の解約レコードから判断。
  120. 120. 失敗談
  121. 121. ドメインモデル関連 ドメインモデルが古い ドメイン層関連 Policyクラスの乱立
  122. 122. データアクセス層関連 Repositoryのsaveメソッド 他集約のRepositoryを操作 SQLに業務ロジックが混在
  123. 123. 失敗談 ドメインモデルが古い
  124. 124. ドメインモデルが古い 内容 日々変化するドメインモデルが最新化されない。 問題点 値オブジェクトを全部管理していたので、更新が追い付かない。 最新のドメインモデルが把握できない。 対策 最初に作成するドメインモデルとKeepするドメインモデルを分 離。 Keepのドメインモデルは重要な概念や本質のみ。
  125. 125. ドメインモデルが古い 最初に作成する ドメインモデル
  126. 126. ドメインモデルが古い Keepする ドメインモデル
  127. 127. 失敗談 Policyクラスの乱立
  128. 128. Policyクラスの乱立 内容 業務チェックのために、ドメイン層にPolicyクラスを用意。 問題点 エンティティから業務ロジックが抜けていく(エンティ ティ貧血症)。 対策 基本的には、エンティティに業務チェックを記述。 明示的にクラス化したい業務チェックのみ、専用のクラス を用意。
  129. 129. Policyクラスの乱立 Policyパッケージを 作った時点で負け
  130. 130. 失敗談 Repositoryのsaveメソッド
  131. 131. Repositoryのsaveメソッド 内容 永続化のメソッドをsaveメソッドのみで対応。 問題点 テーブル構成がドメイン層に浸食。 saveメソッドでどのテーブルが登録・更新されるか不明。 saveメソッドをメンテナンスできるメンバーが限定。 対策 業務イベントごとに専用のメソッドを用意。
  132. 132. 失敗談 他集約のRepositoryを操作
  133. 133. 他集約のRepositoryを操作 内容 他集約のRepositoryをデータアクセス層で操作。 問題点 アプリケーション層のコードだけでは関連する集約が把握 できず、全てのコードを読む必要がある。 影響範囲の特定に時間がかかる。ミスする。 対策 他集約のRepositoryは操作しない。
  134. 134. 失敗談 SQLに業務ロジックが混在
  135. 135. SQLに業務ロジックが混在 内容 SelectのWhere句に業務ロジックが記述。 問題点 業務ロジックがドメイン層から流出。 いつかの仕様変更でバグの温床に。 対策 可能な限り業務ロジックはドメイン層に集約。
  136. 136. 検索条件は主キーのみにして ステータスの絞り込み条件はド メイン層で記述
  137. 137. まとめ
  138. 138. DDD本と現場での実践を 行ったり来たりして 理解を深めていくことが重要
  139. 139. サービスが存在する限り 変化し続け 成長し続け 価値を届け続ける ソフトウェアを作ることが重要
  140. 140. ご静聴 ありがとうございました。

×