$30 off During Our Annual Pro Sale. View Details »

Learning DDD輪読会#9 / Learning DDD Book Club #9

Learning DDD輪読会#9 / Learning DDD Book Club #9

株式会社Showcase Gig主催の輪読会の資料です。
https://showcase-gig.connpass.com/event/255059/

suzushin54

July 28, 2022
Tweet

More Decks by suzushin54

Other Decks in Programming

Transcript

  1. 『Learning Domain-Driven Design』
 📚 輪読会 #9🐒
 Chapter7. Modeling the Dimension

    of Time 
 #lddd_rindoku 2022/07/28
 株式会社Showcase Gig 
 @suzushin54

  2. Disclaimer
 • 本スライドは、以下の書籍を要約・引用の範囲内で紹介します。 
 ◦ Vladik Khononov『Learning Domain-Driven Design: Aligning

    Software Architecture and Business Strategy』Oreilly & Associates Inc (2021/11/2) 
 ◦ https://www.oreilly.com/library/view/learning-domain-driven-design/9781098100124/ 
 • 原文、正確な翻訳文は著作権法および翻訳権に抵触するため掲載しません。 
 
 2
  3. Overview
 Modeling the Dimension of Time / 時間の次元のモデリング 
 •

    7-1. Event Sourcing / イベントソーシング 
 ◦ Search / 検索
 ◦ Analysis / 分析 
 ◦ Source of Truth / 信頼できる情報源 
 ◦ Event Store / イベントストア 
 • 7-2. Event-Sourced Domain Model / イベントソースドメインモデル 
 ◦ Advantages / 利点 
 ◦ Disadvantages / 不利 
 • 7-3. Frequently Asked Questions / よくある質問 
 ◦ Performance / パフォーマンス 
 ◦ Deleting Data / データの削除 
 ◦ Why Can’t I Just…? / なぜできない...? 
 • 7-4. Conclusion / 結論 
 • 7-5. Exercise / エクササイズ 
 3
  4. Chapter7. Modeling the Dimension of Time / 時間の次元のモデリング
 • 前章では、ドメインモデルパターンについて学んだ


    • 今回のイベントソースドメインモデルパターン も同じ前提に基づくもの
 ◦ 複雑なビジネスロジック(コアドメインに属するもの) 
 ◦ 戦術的パターンである、値オブジェクト、集約、ドメインイベントを使う 
 • 違いは、イベントソーシングパターンを使うこと
 ◦ 集約の状態を永続化する代わりに、変更を記述したドメインイベントを作成する 
 • この章では、まずイベントソーシングのコンセプトを紹介 
 • そしてドメインモデルと組み合わせてイベントソースドメインモデルとする 
 4
  5. “Show me your flowchart and conceal your tables, and I

    shall continue to be mystified. Show me your tables, and I won't usually need your flowchart; it’ll be obvious.” 
 Brooks, F. P. Jr. (1974). The Mythical Man-Month: Essays on Software Engineering. 
 Reading, MA: Addison-Wesley. 
 6 “私にフローチャートだけを見せて、テーブルは見せないとしたら、私はずっと煙に巻かれたままにな るだろう。逆にテーブルが見せてもらえるなら、フローチャートはたいてい必要なくなる。それだけで、 みんな明白に分かってしまうからだ。” 
 『人月の神話』(フレデリック・ブルックス、滝沢徹 訳、丸善出版、2014年) 
 7-1. Event Sourcing 
 Fred Brooks の推論をもとに、イベントソーシングが従来のデータモデリングや永続化と 
 どう違うのかを理解しよう。 

  6. 7 7-1. Event Sourcing
 • 右はテレマーケティングシステムにおいて 
 潜在顧客(Lead)を管理するテーブル 
 •

    ステータスを見ると、どのような処理サイクルを経てい るか想像することができる 
 ◦ 新規: NEW_LEAD
 ◦ 興味を示さない: CLOSE
 ◦ フォロー電話予約: FOLLOWUP_SET
 ◦ オファー受入: PENDING_PAYMENT
 ◦ 支払失敗: PAYMENT_FAILED
 • テーブルからは多くの情報を収集できる 
 • データモデリングにおいて使われたユビキタス言語も 想定できる
 このテーブルに欠けている情報はなんだろうか? 

  7. 8 7-1. Event Sourcing
 これらの問いはビジネスの悩みを反映しており、 
 データを分析してプロセスを最適化するのは重要 
 • テーブルのデータはリードの現在の状態を記録して

    いるが、どのように現在の状態に至ったのか、という ストーリーが欠落している 
 ◦ 🤔コンバージョンに至るまでに何度電話したの か?すぐ購入に至ったのか? 
 ◦ 🤔過去のデータをもとに、何度も連絡するべき か、すぐ他の見込み客に移行する方が効率的 なのか?
 

  8. 9 7-1. Event Sourcing
 • データモデルに時間の次元を導入 
 • 集約のライフサイクルにおける全ての変化を記録し たイベントを永続化する

    
 
 1. システムによるリード作成 
 2. 2時間後に電話連絡 
 3. 翌週の電話を約束
 4. 連絡先の情報も修正 
 …

  9. 10 7-1. Event Sourcing
 • ドメインイベント(前述の json)からは、顧客の状態を かんたんに予測することができる 
 •

    各イベントに右の変換ロジックを順次適用していく と、表7-1 の状態を生成できる 
 
 • インクリメントしている Version に注目 
 ◦ Entity に加えられた変更の総数を表す 
 • そしてイベントのサブセットを適用すると 
 ◦ 任意の時点の状態を投影して、 
 「タイムトラベル」することができる! 
 次節の検索用モデルと同じなので誤植と思われ る(問い合わせ中)

  10. 12 7-1. Event Sourcing
 Search
 • 検索を実装するユースケースを考えてみる 
 • 前提として、リードの連絡先情報は更新することができる

    
 ◦ 下記のように、今回の例でも更新されている 
 • 営業担当者は変更に気づかず、過去の値で検索するかもしれない 
 初回システム作成時 
 連絡先情報変更後

  11. 13 7-1. Event Sourcing
 Search
 • 投影処理(右)は2つのイベントを使う 
 ◦ Lead

    Initialized
 ◦ Contact Details Changed 
 • 他のイベントは検索モデルに影響しないの で無視すると、以下の状態になる 

  12. 14 7-1. Event Sourcing
 Analysis
 • BI部門から分析に関する依頼があった 
 ◦ 異なるリードに対してコール数を取得したい

    
 ◦ 後でコンバージョンとクローズのデータをフィルタリング して、営業プロセスに活かしたい 
 • 右の投影処理から、以下の状態が生成される 
 ※ 投影されたモデルの永続化については8章にて(CQRS) 

  13. 7-1. Event Sourcing
 15 Source of Truth
 • イベントソーシングのパターンが機能するためには、オブジェクトに対する 


    全ての変更がイベントとして表現され、永続化される必要がある 
 • ただひとつの強い一貫性のあるストレージであり、システムの真実の源である 
 • 一般的にイベントストアと呼ばれる 

  14. 7-1. Event Sourcing
 16 Event Store
 • 追記型ストレージであり、イベントの変更や削除は許可しない 
 •

    エンティティに関するすべてのイベントをフェッチして、追加する 
 NOTE
 本質的に、イベントソーシングパターンは目新しいものではない。金融業界では昔から 
 台帳(取引を記録した追記型ログ)の変更を表すためにイベントを使用している。 

  15. 7-2. Event-Sourced Domain Model
 18 • ドメインモデル
 ◦ 集約の状態を保ち、選択されたドメインイベントを発行する 


    • イベントソースドメインモデル
 ◦ 集約のライフサイクルをモデル化するためにドメインイベントを排他的に使用 
 ◦ 集約の状態に対する変更はドメインイベントとして表現されなければならない 
 
 • イベントソース集約の各操作に対する手順は以下のとおり 
 1. 集約のドメインイベントをロードする
 2. 状態表現の再構築。イベントをビジネス上の意思決定に使用できるかたちに投影する
 3. 集約のコマンドを実行し、ビジネスロジックを実行する。新しいドメインイベントを生成する
 4. 新しいドメインイベントをイベントストアにコミットする
 👉 6章のチケット集約の例に戻って、イベントソース集約の実装を確認しよう 

  16. 7-2. Event-Sourced Domain Model
 19 1 -> 
 2 ->

    
 3 -> 
 4 -> 
 * 集約の公開 I/F の状態変更メソッドはよくコマンドと呼ばれる
 1. 集約のドメインイベントをロードする
 2. 状態表現の再構築。イベントをビジネス上の意思決定に使用できるかたちに投影する
 3. 集約のコマンド* を実行し、ビジネスロジックを実行する。新しいドメインイベントを生成する
 4. 新しいドメインイベントをイベントストアにコミットする

  17. 7-2. Event-Sourced Domain Model
 21 • 前章の実装と違い、IsEscalated は直接操作しない 
 •

    その代わり、イベントのインスタンスを AppendEvent() に渡している 
 👇前回実装 (Domain Model)
 👆今回の実装 (Event-Sourced Domain Model)

  18. 7-2. Event-Sourced Domain Model
 22 • Append されたイベントたちは TicketState クラスの投影ロジックへ渡す

    
 • フィールドの値はイベントのデータに従って変更されていく 
 では、複雑なビジネスロジックを実装する際 に、イベントソーシングを使うメリットを見て いこう

  19. 7-2. Event-Sourced Domain Model
 23 Advantages - 伝統的なモデルと比較したメリット 
 A.

    Time traveling - 時間旅行
 ◦ ドメインイベントを使用して、集約の過去の状態を復元できる 
 B. Deep insight - 深い洞察
 ◦ イベントソーシングはシステムの状態や動作に対する深い洞察を提供できる 
 ◦ 柔軟なモデルを提供でき、ビジネスに重要なコアサブドメインを最適化できる 
 C. Audit log - 監査ログ
 ◦ 永続化されたドメインイベントは集約の状態に起こったすべてのことに関する、 
 一貫性のある監査ログを表す 
 D. Advanced optimistic concurrency management - 高度楽観的並行性管理 
 ◦ 古典的な楽観的同時実行モデルでは変更が衝突すると例外が発生する 
 ◦ イベントソーシングでは既存のイベントを読み込んでから新しいイベントを書き込むまでの間に起 きたことを把握して、続行可能かビジネス的に判断ができる 

  20. 7-2. Event-Sourced Domain Model
 24 Disadvantages - この設計パターンの課題 
 A.

    Learning curve - 学習曲線
 ◦ 従来のデータ管理手法と異なるため、チームに訓練と慣れが必要 
 B. Evolving the model - モデルの進化 
 ◦ イベントソースモデルを進化させるのは難しい 
 ▪ イベントソーシングの厳密な定義では、イベントは不変であるとされる 
 ▪ イベントのスキーマを調整する必要がある場合は?...とても難しい 
 C. Architectural complexity - アーキテクチャの複雑性 
 ◦ イベントソーシングの実装は、全体的な設計を複雑にする 
 ▪ 次章の CQRS についての議論でより詳細に 
 ◦ また、10章では実装パターンの選択について、経験則を学ぶ 

  21. 7-3. Frequently Asked Questions
 26 Performance
 「イベントから集約の状態を再構成する実装は、システムのパフォーマンスにマイナスの影響を与えま す。 イベントが追加されるにつれて、パフォーマンスが低下します。どうしたら良いでしょうか?」
 •

    確かに計算リソースは必要で、イベント数が増えるに従って影響は高まる 
 • 数百〜数千のイベントを処理した場合のベンチマークを取ることが重要 
 ◦ その結果を、集約の予想寿命(平均寿命の間に記録されるであろうイベント数)と比較する 
 • 殆どのシステムで、集約あたり10,000以上のイベントが発生すると影響が顕著に 
 • 多くのシステムでは、集約の平均寿命において100イベントを超えることはない 

  22. 7-3. Frequently Asked Questions
 27 • それでもパフォーマンスの影響が出る場合は、 
 スナップショットという実装パターンもある
 •

    右図は、以下の実装ステップで実現する 
 1. プロセスは新しいイベントから継続的に 
 投影を生成、キャッシュする 
 2. インメモリー投影は、集約に対するアクションを 実行するのに必要
 a. キャッシュから現在の状態の投影をフェッチ
 b. プロセスは後のバージョンのイベントをフェッチ
 c. 追加イベントはスナップショットにインメモリで適用 する

  23. 7-3. Frequently Asked Questions
 28 「このモデルは膨大な量のデータを生成します。スケールできますか?」
 • イベントソースモデルはスケーリングが容易 
 •

    集約に関する操作は、単一の集約のコンテキストで実行されるので、 
 イベントストアは集約 ID でシャーディング可能 

  24. 7-3. Frequently Asked Questions
 29 Deleting Data
 「イベントストアは追記型の DB ですが、例えば

    GDPR に準拠するためにデータを物理的に削除する必 要がある場合はどうすればよいでしょうか?」
 • 忘却可能なペイロードパターン (the forgettable payload pattern) で対応可能
 ◦ 機密情報は暗号化してイベントに含めておく 
 ◦ 暗号化キーは、外部の KVS に保存 
 ◦ キーが特定の集約のID、値が暗号化キー 
 • 機密データを削除する場合、KVS から削除すれば復元できなくなる 
 https://twitter.com/mathiasverraes/status/1127935384313323520 
 https://verraes.net/2019/05/eventsourcing-patterns-forgettable-payloads/ 

  25. 7-3. Frequently Asked Questions
 30 Why Can’t I Just…?
 「テキストファイルにログを書き込んで、監査ログとして使えませんか?」

    
 A. 2つの機構に対する書き込みはエラーが発生しやすく矛盾が生じやすい 
 「ステートベースモデルで作業しつつ、同じDBトランザクションでログ追加できないでしょうか?」 
 A. インフラ観点では一貫性があるが、エラーが起きやすいことは変わりない。 
 また未来のエンジニアがログの書き込みを忘れるかもしれないし、真実ではない情報は劣化する 
 「ステートベースモデルで作業しつつ 、レコードのスナップショットを取って専用の「履歴」テーブルにコピーする データベーストリガーを追加できないのでしょうか」 
 A. 明示的な呼出不要でこれまでの欠点は克服している。しかし単なるフィールドの変更履歴からは「なぜ変 更されたか」というビジネスコンテキストが欠落しており、拡張を制限してしまう 

  26. 7-4. Conclusion
 32 ★ この章では、イベントソーシングパターンと、ドメインモデルの集約における時間の次元のモデ リングについて説明した
 ★ イベントソースドメインモデルでは、集約の状態に対するすべての変更はイベントとして表現す る
 ◦

    これは状態の変更が単にデータベースのレコードを更新する従来のアプローチとは対照的 
 ★ イベントベースモデルでは、イベントを複数の表現モデルに投影する柔軟性がある 
 ◦ 特定のタスクに向けて最適化でき、分析や監査ログなど、システムのデータを深く洞察することが 重要である場合に適している 

  27. Exercise / エクササイズ
 34 1. ドメインイベントと値オブジェクトの関係について、正しい記述はどれか 
 A. ドメインイベントは、ビジネスドメインで何が起こったかを記述するために値オブジェクトを 使用する


    B. イベントソースのドメインモデルを実装する場合、値オブジェクトはイベントソースの集約に リファクタリングする必要がある
 C. 値オブジェクトはドメインモデルパターンに関連しており、イベントソースドメインモデルで はドメインイベントに置き換えられる 
 D. すべて誤り

  28. Exercise / エクササイズ
 35 1. ドメインイベントと値オブジェクトの関係について、正しい記述はどれか 
 A. ドメインイベントは、ビジネスドメインで何が起こったかを記述するために値オブジェクトを 使用する


    B. イベントソースのドメインモデルを実装する場合、値オブジェクトはイベントソースの集約に リファクタリングする必要がある
 C. 値オブジェクトはドメインモデルパターンに関連しており、イベントソースドメインモデルで はドメインイベントに置き換えられる 
 D. すべて誤り

  29. Exercise / エクササイズ
 36 2. イベントから状態をプロジェクションするオプションに関して正しい記述はどれか 
 A. 集約のイベントから単一の状態表現を投影することができる 


    B. 複数の状態表現をプロジェクションすることができるが、ドメインイベントは複数のプロジェ クションをサポートする方法によってモデル化する必要がある 
 C. 複数の状態表現をプロジェクションすることができ、将来的にもいつでも追加することがで きる
 D. すべて誤り

  30. Exercise / エクササイズ
 37 2. イベントから状態をプロジェクションするオプションに関して正しい記述はどれか 
 A. 集約のイベントから単一の状態表現を投影することができる 


    B. 複数の状態表現をプロジェクションすることができるが、ドメインイベントは複数のプロジェ クションをサポートする方法によってモデル化する必要がある 
 C. 複数の状態表現をプロジェクションすることができ、将来的にもいつでも追加することがで きる
 D. すべて誤り

  31. Exercise / エクササイズ
 38 3. ステートベース集約とイベントソース集約の違いについて、正しい記述はどれか 
 A. イベントソース集約はドメインイベントを生成できるが、 


    ステートベース集約はドメインイベントを生成できない 
 B. どちらもドメインイベントを生成するが、イベントソース集約だけが信頼できる情報源として ドメインイベントを使用する
 C. イベントソース集約は、すべての状態遷移に対してドメインイベントが生成されることを保 証する
 D. BとCの2つが正しい

  32. Exercise / エクササイズ
 39 3. ステートベース集約とイベントソース集約の違いについて、正しい記述はどれか 
 A. イベントソース集約はドメインイベントを生成できるが、 


    ステートベース集約はドメインイベントを生成できない 
 B. どちらもドメインイベントを生成するが、イベントソース集約だけが信頼できる情報源として ドメインイベントを使用する
 C. イベントソース集約は、すべての状態遷移に対してドメインイベントが生成されることを保 証する
 D. BとCの2つが正しい