Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

suzushin54
November 02, 2022

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

suzushin54

November 02, 2022
Tweet

More Decks by suzushin54

Other Decks in Programming

Transcript

  1. 『Learning Domain-Driven Design』
 📚 輪読会 #15🐒
 Chapter 13. Domain-Driven Design

    in the Real World
 #lddd_rindoku
 2022/11/02
 株式会社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/9781098 100124/
 • 原文、正確な翻訳文は著作権法および翻訳権に抵触するため掲載しません。 
 
 2
  3. Overview
 Domain-Driven Design in the Real World / ドメイン駆動設計の実際
 •

    13.1 Strategic Analysis / 戦略的分析
 • 13.2 Modernization Strategy / モダナイゼーション戦略
 • 13.3 Pragmatic Domain-Driven Design / 実用的なドメイン駆動設計
 • 13.4 Selling Domain-Driven Design / ドメイン駆動設計を売る
 • 13.5 Conclusion / 結論
 • 13-6 Exercise /エクササイズ
 3
  4. Chapter 13. Domain-Driven Design in the Real World 
 •

    これまでに学んだ DDD を Greenfield project に適用したらどれだけ楽しいでしょう? 
 ◦ 同僚は DDD をよく理解していて、効果的なモデルを設計し、ユビキタス言語を使う 
 ◦ PJが進むと境界づけられたコンテキストが明確になり、ドメインモデルを保護できるように 
 ◦ 戦術的設計はビジネス戦略に沿っているため、コードは常に素晴らしい状態にある 
 • これを経験できる可能性は、宝くじに当たることと同じくらい可能性が高い 
 • 皮肉なことに Brownfield project が最も DDD の恩恵を受けられる
 ◦ ビジネスの可能性が証明されていて、技術的負債等と戦うため改革が必要な PJ
 ▪ 偶然にも、私たちはエンジニアリングのキャリアのほとんどをそれに費やしている 
 • また、DDD は all-or-nothing という誤解があるが、真実ではない 
 ◦ 全てのパターンや手法を適用する必要はないし、合理的な時間枠の中では事実上不可能 
 • この章では、DDD を現実的に適用するための戦略を学ぶ 
 4 Greenfield project : 新規開発
 Brownfield project : 既存システムやレガシーを考慮する必要がある開発

  5. 13.1 Strategic Analysis
 6 ビジネスドメインの理解
 • まずは会社のビジネスドメインを特定する 
 ◦ 組織のビジネスドメインは何か?

    
 ◦ 顧客は誰か?提供しているサービス・価値は何か? 
 ◦ どのような企業や製品と競合しているのか? 
 ▪ これらの質問に答えることで、その企業の目標を俯瞰的に把握できる 
 • 次にそのドメインに注目し、ビジネスの構成要素であるサブドメインを探していく 
 ◦ 最初のヒューリスティックは「会社の組織図」 
 ▪ 組織がどのように連携して、事業領域で競争力を発揮しているかをチェック 
 ▪ さらに、特定の種類(specific types)のサブドメインが存在する兆候を探す 

  6. 13.1 Strategic Analysis
 7 ビジネスドメインの理解 - コアサブドメイン
 • コアサブドメインの特定には、競合との差別化ポイントを探す 


    ◦ 競合にはない “secret sauce” を持っているか
 ▪ e.g. 特許, 自社アルゴリズム等の知財
 ◦ 競争優位性、ひいてはコアサブドメインは、必ずしもテクニカルなものではない 
 ▪ e.g. トップレベルの人材採用能力、ユニークな芸術的デザイン
 • もう1つの強力かつ不幸なヒューリスティックは、最悪な設計のソフトウェアコンポーネントを 
 特定すること
 ◦ それはすべてのエンジニアが嫌う “Big ball of mud”
 ◦ ビジネスリスクがあるためスクラッチで書き直したくない 
 ◦ 重要なのは、レガシーシステムは既製品のシステムでは置き換えられないということ 
 ▪ これは汎用サブドメインとなり、これに手を加えるとビジネスリスクを伴う 

  7. 13.1 Strategic Analysis
 8 ビジネスドメインの理解 - 汎用サブドメイン
 • 汎用サブドメインを特定するには以下を確認 


    ◦ 既製のソリューション 
 ◦ サブスクリプションサービス 
 ◦ OSSの統合
 • 1章で触れたように、競合も同じソリューションを利用できる 
 ◦ 同じソリューションを利用している企業はビジネス上の影響がないはず 

  8. 13.1 Strategic Analysis
 9 ビジネスドメインの理解 - サポートサブドメイン
 • 既製のソリューションでは置き換えられないが、競争優位性をもたらさないもの 


    • コードが荒れていれば変更頻度が低いのでエンジニアの反応は少ない 
 ◦ コアサブドメインほど深刻な影響はない 
 ◦ > You don’t have to identify all of the core subdomains.
 ※ おそらく supporting subdomains の誤記
 ◦ 中規模の企業でもすべて特定するのは現実的ではない 
 ◦ その代わりに...
 ✅ 全体的な構造を把握する 
 ✅ 担当するシステムに最も関連性の高いサブドメインに注意を払う 

  9. 13.1 Strategic Analysis
 10 現在の設計を調査する
 • 問題領域に慣れたら、解決策と設計上の決定について調査していく 
 ◦ まずはハイレベルコンポーネントの構成要素から始める

    
 ▪ 必ずしも DDD の Bounded Context ではなく、サブシステムに分解する境界 
 • 特徴的な性質として、コンポーネントのライフサイクルの分離が挙げられる 
 ◦ たとえモノレポであっても、単一のコードベースだったとしても、 
 独立して進化・テスト・デプロイが可能であるかチェックしていく 

  10. 13.1 Strategic Analysis
 11 現在の設計を調査する - 戦術的設計の評価
 • 各コンポーネントに対し、チェックしていく 


    ◦ どんなビジネスサブドメインが含まれているか 
 ◦ どんな技術的設計の決定がされているか 
 • そしてそのソリューションは...
 ◦ 問題の複雑さに合っているか? 
 ◦ より精巧なデザパタが必要な部分はあるか? 
 ◦ 既製のソリューションは利用できないか? 
 

  11. 13.1 Strategic Analysis
 12 現在の設計を調査する - 戦略的設計の評価
 • ハイレベルのコンポーネントに関する知識から、現在のコンテキストマップを作成 


    ◦ そしてそれを Bounded context であるかのようにする 
 ◦ コンポーネント間の関係を特定し、追跡する 
 ◦ 最後にそれを分析して、アーキテクチャを評価する。不適切な設計判断があるか? 
 ▪ 複数のチームが同じコンポーネントに関わっている 
 ▪ コアサブドメインの重複した実装や外部委託 
 ▪ 外部サービスやレガシーから広がった不器用なモデル …etc
 ◦ これらの洞察はモダナイゼーション戦略の出発点 
 ◦ より深い知識を得た上で、失われたドメイン知識を探そう 
 ▪ 11章で述べたように、さまざまな理由で失われることがある 
 ▪ EventStorming によって知識の回復に努めよう 

  12. 13.2 Modernization Strategy
 14 • “big rewrite” は殆ど成功しない。経営陣がその試みを支持することも稀 
 •

    安全な改善アプローチは、大きく考えても小さく始めること 
 ◦ どこに投資すべきかを戦略的に決定する 
 ◦ その前提条件が、サブドメインを分割する境界 
 ◦ 図13-1 のように、論理的な境界をサブドメインと一致させることから始めると良い 
 ▪ 技術スタックによっては、 namespace, module and package
 ◦ モジュール調整は比較的安全なリファクタの 1つ 
 

  13. 13.2 Modernization Strategy
 15 戦略的なモダナイゼーション
 • 早々に小さな Bounded contexts に分解するのは危険(10章参照)


    ◦ MSA は次章で説明する
 • 今は論理的境界を物理的境界に変えて最も価値が得られる場所を探す 
 ◦ そのためのプロセスを 図13-2 に図解👇

  14. 13.2 Modernization Strategy
 16 • 自分に問いかける質問
 ◦ 複数のチームが同じコードベースで作業しているか? 
 ▪

    その場合、チームごとに Bounded contexts を定義して開発を分ける 
 ◦ 異なるコンポーネントで相反するモデルが使用されていないか 
 ▪ その場合、競合するモデルを別々の Bounded contexts に移動する
 • 最低限の Bounded contexts が揃ったら...
 ✅ それらの関係や統合パターンを調べる 
 ✅ それぞれのチームがどのようにコミュニケーションして、コラボしているか確認する 
 ✅ 特にアドホックな統合や共有カーネルの場合、チームはゴールを共有できているか 

  15. 13.2 Modernization Strategy
 17 戦略的なモダナイゼーション - 統合パターン別の解決できる問題 
 カスタマーとサプライヤーの関係 


    • 組織の成長によってコミュニケーションやパートナーシップが無効になっていないか 
 ◦ もし持続不可能なら、適切な関係性にリファクタする 
 腐敗防止層
 • 上流サービスの I/F 変更やレガシーシステムから Bounded contexts を保護するのに役立つ 
 オープンホストサービス 
 • 実装が頻繁に変更され、コンシューマに影響を与える場合はこれを検討する 
 ◦ 実装モデルを、 Public API から切り離すということ 
 別々の道
 • 特に大規模な組織では共有機能の共同開発の必要があり、チーム間の摩擦が発生しうる 
 ◦ コアサブドメインではない場合は、それぞれ別の方法でソリューションを実装すればよい 

  16. 13.2 Modernization Strategy
 18 戦術的な近代化
 • 戦術的観点から、ビジネス価値と実装戦略の “painful” なミスマッチを探す
 ◦

    e.g. 複雑なコアサブドメインのモデルがトランザクションスクリプトやアクティブレコードなど
 • ビジネスの成功に直接影響するコンポーネントは最も頻繁に変更する必要がある 
 ◦ 貧弱な設計では、維持・進化させるのに苦労してしまう 

  17. 13.2 Modernization Strategy
 19 ユビキタス言語の育成
 • 設計を成功させるためには、ドメイン知識の獲得と効果的なドメインモデルの構築 
 ◦ そのためには、ユビキタス言語が不可欠

    
 • ドメイン知識の獲得には EventStorming
 ◦ 特にコードの文書化が進んでおらず混乱の中にある場合はドメインエキスパートと調査する 
 ◦ 機能に関連するすべてのひとを集め、ビジネスドメインを探る 
 • ドメイン知識とモデルを手に入れたら、実装パターンの検討に入る 
 ◦ 10章で説明した設計ヒューリスティックを使う 
 
 • 続いて、2つのモダナイゼーション戦略について見ていく 

  18. 13.2 Modernization Strategy
 21 1. ストラングラーパターン
 • 名付けの木と同じ成長に基づくもの 
 1.

    新しい Bounded contexts (the strangler) を作成
 2. そこへ新しい要件を実装していき、レガシーの機能も移行していく
 3. Hotfix などを除き、レガシーの開発は停止する
 4. 最終的にはすべてが the strangler へ移行され、アナロジーどおりレガシーは死に至る
 
 https://cmfirstgroup.com/modernize-with-the-strangler-application-patte rn-and-microservices/

  19. 13.2 Modernization Strategy
 23 • それぞれの Bounded contexts は独立したサブシステムであるため、 


    本来は DB を共有することは原則に違反する 
 ◦ ストラングラーパターンを実装するときはこのルールを緩める(共有しても良い) 
 ◦ いち早くレガシーを引退させ、新しいコードベースからのみ使うようにするのが条件 

  20. 13.2 Modernization Strategy
 24 2. 戦術的な設計上の決定をリファクタする 
 • レガシーコードの最新化には注意すべき 2つのことがある


    ◦ 小さな漸進的なステップの方が安全 
 ▪ いきなり Transaction Script などから Event Sourced Domain Model にはリファクタしない
 ▪ State-based な集約を設計する中間ステップを取り、効果的な集約を見つけることに注力する
 ◦ Domain Model へのリファクタは、アトミックな変更である必要はない
 ▪ パターンの要素を徐々に導入していくことが可能
 • 考えられる Value Object を探すことから始める
 ◦ 本格的な Domain Model でなくても、Immutable objects は複雑さを軽減してくれる 
 • 最後に、必要であればレガシーをリファクタする際に腐敗防止層を使おう 
 ◦ 新しいコードベースを古いモデルから保護できる
 ◦ オープンホストサービスを実装して公開言語を使うことで、コンシューマをレガシーの変更から保護できる

  21. 13.3 Pragmatic Domain-Driven Design
 26 DDD の適用は all-or-nothing の努力ではない
 •

    何らかの理由で戦術的パターンが上手く機能しないかもしれない 
 • 他のデザパタが特定のドメインでうまく機能するとしたら、それで問題ない 
 “As long as you analyze your business domain and its strategy, look for effective models to solve particular problems, and most importantly, make design decisions based on the business domain’s needs: that’s domain-driven design! 
 It’s worth reiterating that domain-driven design is not about aggregates or value objects. Domain-driven design is about letting your business domain drive software design decisions.” 
 ビジネスドメインとその戦略を分析し、特定の問題を解決するための効果的なモデルを探し、そして最も重要なこと、ビジネスド メインの要求に基づいて設計を決める限り、それはドメイン駆動設計です!
 ドメイン駆動設計とは集約や値オブジェクトのことではないと、改めて強調しておきます。ドメイン駆動設計とは、ビジネスドメイ ンにソフトウェアの設計上の意思決定をさせることです。

  22. 13.4 Selling Domain-Driven Design
 28 「DDD は素晴らしいが、チームや経営陣に売り込むにはどうしたら?」 
 • カンファレンスでほぼ毎回聞かれる、難しくて重要な質問

    
 • 個人的には売るのは嫌いだが、設計することとはアイデアを売ることでもある 
 • 組織を大きく変えるには経営者の支持が不可欠 
 ◦ しかし、トップレベルのマネージャーが DDD を理解しているか、この手法のビジネス価値を学ぶた めに時間を投資する意志がないと、 DDD は彼らにとって重要事項にはならない 
 • しかし、幸いなことに、DDD を使えないというわけではない

  23. 13.4 Selling Domain-Driven Design
 29 DDD の覆面調査
 • DDD を組織的な戦略ではなく、専門的なツールボックスの一部にする

    
 • パターンとプラクティスは技術であり、あなたがエンジニアならそれを使えば良い 
 • DDD を日々の仕事に取り入れるにはどうしたらよいか考えてみよう 

  24. 13.4 Selling Domain-Driven Design
 30 DDD の覆面調査 - ユビキタス言語
 •

    ユビキタス言語の使用は、DDD の基礎となるプラクティス
 ◦ ドメイン知識の発見、コミュニケーション、効果的なモデリングに必須 
 ◦ ステークホルダーの会話に注意深く耳を傾ける 
 ◦ 技術的な専門用語からビジネス的な意味へと、用語の使い方を優しく誘導する 
 ◦ 矛盾した用語がないか確認し、説明を求める 
 • 同じものに複数の名称がある場合、その理由を探す
 ◦ 文脈を探して明示する。意味が同じであれば、 1つの用語を使うようにお願いする
 • このような努力はミーティングの場でなくても良い
 ◦ ウォータークーラー(オフィスの井戸端会議)やコーヒーブレイクはとてもよい機会
 • ドメインエキスパートとドメインについて話し、彼らの言葉を使ってみよう 
 ◦ 問題領域について学ぶことに真摯なエンジニアには喜んで協力してくれる 
 • 最も重要なのは、コードとプロジェクトに関するすべてのコミュニケーションで、 
 ユビキタス言語を使用すること
 ◦ 組織で長らく使われてきた用語を変えるには時間が掛かるが、いずれは定着する 

  25. 13.4 Selling Domain-Driven Design
 31 DDD の覆面調査 - Bounded contexts


    • 分解を検討する場合は Bounded context パターンの原理の背後にあるものを解消する 
 ◦ なぜ、すべてのユースケースに対して単一のモデルを設計するのではなく、 
 問題志向のモデルを設計する方が良いのか? 
 ▪ 「オールインワン」のソリューションが何に対しても有効であることはほとんどないから 
 ◦ なぜ Bounded context は競合するモデルをホストできないのか? 
 ▪ 認知負荷とソリューションの複雑さが増すから 
 ◦ なぜ複数のチームが同じコードベースで作業するのは良くないのか? 
 ▪ チーム間の摩擦と協力が妨げられるから 
 • Bounded context integration パターンについても理由は同じ 
 ◦ 各パターンが解決すべき問題を理解していることを確認する 

  26. 13.4 Selling Domain-Driven Design
 32 DDD の覆面調査 - 戦術的設計の決定
 •

    議論するとき、権威に訴えるのはやめよう󰢃
 e.g. 「DDDの本がそう言っているから、ここでは集約を使おう!」 
 • ロジックをアピールしよう󰢨
 💬 なぜトランザクションの境界を明示することが重要なのか? 
 ✅ データの一貫性を守るため
 💬 なぜトランザクションは、複数の集約を変更できないのか? 
 ✅ 一貫性の境界が正しいことを確認するため 
 💬 なぜ集約の状態は、外部コンポーネントによって直接変更できないのか? 
 ✅ 関連するすべてのビジネスロジックが配置され、重複しないようにするため 
 💬 なぜ集約の機能の一部をストアドプロシージャにオフロードできないのか? 
 ✅ ロジックが重複しないようにするためです 
 💬 なぜ集計境界を小さくするように努力しなければならないのか? 
 ✅ トランザクションの範囲が広いと集約の複雑さが増してパフォーマンスにも影響を及ぼすから 
 💬 なぜ、イベントソーシングの代わりに、ログファイルにイベントを書き込めないのか? 
 ✅ 長期的なデータの一貫性が保証されないから 

  27. 13.4 Selling Domain-Driven Design
 33 DDD の覆面調査 - Event sourced

    domain model
 • メリットが多くても、多くの人は Event Sourcing を急進的・過激に思う
 ◦ 解決策は、ビジネスドメインにこの決定を任せる 
 • ドメインエキスパートに話を聞こう 
 ◦ State-based model と Event-based model を見せる
 ◦ Event Sourcing のメリット、特に時間の側面について説明する 
 ◦ 彼らは Event Sourcing が提供する洞察力の高さに感嘆し、自ら提唱するようになる 
 

  28. 13.5 Conclustion / 結論
 35 • 現実のシナリオで DDD を活用するテクニックを学んだ
 •

    Brownfield PJ やレガシーに取り組むときも、常にドメイン分析から始める 
 ◦ 会社の目標やそれを達成するための戦略は何か? 
 ◦ 組織構造と既存のソフトウェア設計上の決定を利用し、組織のサブドメインと種類を特定 
 • この知識を基に、モダナイゼーションを計画する 
 • Pain point を探す。最もビジネス価値の高いものを探す 
 • レガシーのモダナイゼーションは、リファクタまたは関連するコンポーネントの交換によって実 施する
 • DDD が採用されていない組織でも、DDD のツールを使用することができる 

  29. Exercise
 37 1. Brownfield PJ に DDD のツールと実践を導入したい。最初のステップは何か? 
 A.

    すべてのビジネスロジックを Event sourced domain model にリファクタする
 B. 組織のビジネスドメインとその戦略を分析する 
 C. システムコンポーネントが適切な Bounded contexts の原則に従うように改善する
 D. Brownfield PJ で DDD を使うことは不可能

  30. Exercise
 38 1. Brownfield PJ に DDD のツールと実践を導入したい。最初のステップは何か? 
 A.

    すべてのビジネスロジックを Event sourced domain model にリファクタする
 B. 組織のビジネスドメインとその戦略を分析する 
 C. システムコンポーネントが適切な Bounded contexts の原則に従うように改善する
 D. Brownfield PJ で DDD を使うことは不可能

  31. Exercise
 39 2. ストラングラーパターンは、移行プロセスにおいて DDD の核となる原則と
 どのような点で矛盾しているか? 
 A. 複数の

    Bounded contexts が共有データベースを使用している 
 B. 近代化された Bounded contexts がコアサブドメインである場合、
 その実装は古い実装と新しい実装で重複してしまう 
 C. 複数のチームが同じ Bounded contexts で作業している
 D. AとB

  32. Exercise
 40 2. ストラングラーパターンは、移行プロセスにおいて DDD の核となる原則と
 どのような点で矛盾しているか? 
 A. 複数の

    Bounded contexts が共有データベースを使用している 
 B. 近代化された Bounded contexts がコアサブドメインである場合、
 その実装は古い実装と新しい実装で重複してしまう 
 C. 複数のチームが同じ Bounded contexts で作業している
 D. AとB

  33. Exercise
 41 3. Active Record ベースのビジネスロジックをそのまま Event sourced domain modelにリファ

    クタすることが一般的に良くないのはなぜか? 
 A. State-base のモデルは、学習プロセス中に集約の境界をリファクタすることを容易にする 
 B. 大きな変更は徐々に導入する方が安全 
 C. AとBの両方
 D. 上記のどれでもない。Transaction Script でさえ、Event sourced domain model にその ままリファクタリングするのは合理的 

  34. Exercise
 42 3. Active Record ベースのビジネスロジックをそのまま Event sourced domain modelにリファ

    クタすることが一般的に良くないのはなぜか? 
 A. State-base のモデルは、学習プロセス中に集約の境界をリファクタすることを容易にする 
 B. 大きな変更は徐々に導入する方が安全 
 C. AとBの両方
 D. 上記のどれでもない。Transaction Script でさえ、Event sourced domain model にその ままリファクタリングするのは合理的 

  35. Exercise
 44 4. あなたが集約パターンをチームに紹介しているとき、こんな質問を受けました。 
 「なぜ集約はすべての可能な Entity を参照することができないのか。 
 そしてそれ故に、1つの場所からビジネスドメイン全体を横断することができないのか」

    あなたはど のように答えますか?
 A. Bounded context全体に境界を持つ集約は、Bounded context のすべてのデータを1つの大 きなトランザクションの一部とすることができる。また、この方法によるパフォーマンスの問題は、最 初から明らかになる可能性が高い。 
 そうなれば、トランザクションの境界は取り除かれることになり、集約に存在する情報は強い一貫性 があると仮定することはできなくなる。