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

Learning_Domain-Driven_Design輪読会__10.pdf

issei
August 31, 2022

 Learning_Domain-Driven_Design輪読会__10.pdf

https://showcase-gig.connpass.com/event/256695/
LDDDチャプター8章の資料です

issei

August 31, 2022
Tweet

More Decks by issei

Other Decks in Programming

Transcript

  1. Learning Domain-Driven Design 輪読会 #10 Chapter 8. Architectural Patterns 株式会社Showcase

    Gig 寺田 一生
  2. はじめに • この資料は「Learning Domain-Driven Design」の Chapter 8を意訳・要約したものです • 資料の内容は原文の表現や内容と異なることがあり ます

  3. Overview • Business Logic Versus Architectural Patterns • Layered Architecture

    • Ports & Adapters • Command-Query Responsibility Segregation • Scope • Conclusion • Exercises
  4. Chapter 8. Architectural Patterns • これまでの章で、ビジネスロジックをモデリング/実装する様々な方法を議論してき た • Chapter 8では、より広いコンテキストで戦術的な設計を決定する方法を追求して

    いく ◦ システムのコンポーネント間の相互作用や依存関係をオーケストレーションする様々な方法
  5. Business Logic Versus Architectural Patterns

  6. Business Logic Versus Architectural Patterns • ソフトウェアはビジネスロジックを表すコード以外にも、機能要件・非機能要件を満 たすために、より多くのコードが必要 ◦ 状態を保持するためのストレージ

    ◦ 外部システムや情報プロバイダシステムとの接続 • コードベースは様々な関心事に対処するため、ビジネスロジックが様々なコンポー ネント間に漏れ出す ◦ ユーザーインターフェースやデータベースに実装されたり、複数のコンポーネントに複製されていた りする • 結果、ビジネスロジックを変更したくなった時に、コードベースのどの部分に影響が 及ぶか分からなくなる(修正すべきコードを見逃しやすい) ◦ メンテナンスコストが劇的に増大する
  7. Business Logic Versus Architectural Patterns • アーキテクチャパターンはコードベースを役割ごとに整理する原則を導入し、それら の依存関係を明確にする ◦ ビジネスロジックとインプット

    /アウトプット、インフラのコンポーネントの繋がり ◦ コンポーネントどうしはどんな情報を共有し、参照しているか • コードベースを整理するのに適切な方法やアーキテクチャパターンを選定できると 短期的にも長期的にもメリットがある ◦ 短期的にはビジネスロジックの実装が非常に楽になる ◦ 長期的にはメンテナンスの苦しみが緩和される • 優れた3つのアーキテクチャパターン(Layerd Architecture, Port & Adopter, CQRS)をみていこう!
  8. Layered Architecture

  9. Layered Architecture • Presentation Layer • Business Logic Layer •

    Data Access Layer • Communication Between Layers • Variation • When to Use Layered Architecture
  10. Layered Architecture • Layered Architectureは最も一般的なアーキテ クチャパターン • コードベースを水平な層にまとめる • 各層は、消費者との相互通信、ビジネスロジック

    の実装、データの永続化などの関心事に対応 する • 右図は3つの層からなる典型的なLayered Architecture ◦ Presentation layer (PL) ◦ Business logic layer (BLL) ◦ Data access layer (DAL)
  11. Layered Architecture プレゼンテーション層 • 消費者との相互通信のためのUIを実装する • 本来この層は、webインターフェースやデスクトップアプリケーションなどの視覚的 なインターフェース • モダンなシステムではスコープが広がっており、同期・非同期を問わずプログラム

    の動作のトリガー全てを指す ◦ Graphical user interface (GUI) ◦ Command-line interface (CLI) ◦ 他システムと接続する API ◦ メッセージブローカーでのイベントのサブスクリプション ◦ 外に発信するイベントのメッセージトピック
  12. Layered Architecture プレゼンテーション層 • 全ての例に言えることは、システムは外部からリクエストを受け取って、そのアウト プットを返す • プレゼンテーション層はプログラムの公のインターフェース

  13. Layered Architecture ビジネスロジック層 • 名前の通り、プログラムのビジネスロジックを実装しカプセル化する層 • Eric Evans曰く、この層はソフトウェアの心臓 • 5-7章で述べたビジネスロジックパターンを実装する

    ◦ アクティブレコード ◦ ドメインモデル
  14. Layered Architecture データアクセス層 • 永続化メカニズムへのアクセスを行う • 本来はデータベースへの参照 • PLと同様にモダンなシステムではスコープが広がっている •

    1つは、NoSQL革命以来、1つのシステムが複数のデータベースで動作することが 一般的になったこと ◦ ドキュメントストアは、以下のように機能させることができる ▪ 運用データベース ▪ 動的なクエリのための検索インデックス ▪ パフォーマンスを最適化するためのインメモリデータベース
  15. Layered Architecture データアクセス層 • 2つ目は、もはや情報を蓄積する媒介者として伝統的なデータベースだけではなく なっていること ◦ cloud-basedなオブジェクトストレージ  (AWS S3,

    Google Cloud Strage) ◦ システムの内部で用いられるメッセージバス • 3つ目は、様々な外部の情報プロバイダと接続すること ◦ 外部システムが提供する APIやクラウドベンダのマネージドサービスなど ▪ 言語翻訳 ▪ 株式市場データ ▪ 音声転写
  16. Layered Architecture レイヤー間のコミュニケーション • トップダウンなコミュニケーションモデル • それぞれのレイヤーは下層のレイヤーに依存してい る • 実装の関心事を分割できて、レイヤー間で共有する

    知識を減らせる ◦ 右図ではPLはBLLのみ参照しており、DALで はデザインの決定などの知識はない
  17. Layered Architecture Variation • サービスレイヤを追加するのも一般的 • サービスレイヤにおいて利用可能なオペレーションのセットを確立し各オペレー ションにおけるアプリのレスポンスを調整することで、アプリの境界を定義する。 (Patterns of

    Enterprise Application Architecture)
  18. Layered Architecture Variation(サービス層) • サービス層はプレゼンテーション層とビジネ スロジック層の中継 • 右のコードのMVCコントローラはプレゼン テーション層にあり新規ユーザを作るエンド ポイントを公開している

    • ユーザのアクティブレコードオブジェクトを 使って新しいインスタンスを作り、セーブして いる • 更に、エラーの際に適したレスポンスを作る ようにデータベーストランザクションを貼って いる
  19. Layered Architecture Variation(サービス層) • プレゼンテーション層とビジネスロジック 層の更なる分離のために、例の処理は サービス層に移動すべき • アーキテクチャパターンの文脈における サービス層は論理的な境界で、物理的な

    サービスではないことに注意
  20. Layered Architecture Variation(サービス層) • サービス層はビジネスロジックのファサー ド(正面,正門)になる • パブリックインターフェースのメソッドに対 応するインターフェースを公開し、下層の 必要なオーケストレーションをカプセル化

  21. Layered Architecture Variation(サービス層) • 右図のメソッド(CreateCampaign …)は 全てシステムのパブリックインターフェー ス • かつ、プレゼンテーションに関する実装に

    ついては隠蔽されている • プレゼンテーション層の責務は、サービス 層に必要な入力を与え、その応答を呼び 出し元に伝えることに限定される
  22. Layered Architecture Variation(サービス層) • オーケストレーションロジックをサービス層に移動させてみよう

  23. None
  24. Layered Architecture Variation(サービス層) • 多くのメリットがある ◦ 同じサービス層を使いまわせる ▪ 例えばGUIとAPIで同じオーケストレーションロジックを複製しなくて済む ◦

    関係するメソッドが集まるのでモジュラリティが上がる ◦ プレゼンテーション層とビジネスロジック層が更に切り離せる ◦ ビジネスの機能をテストしやすくなる
  25. Layered Architecture Variation(サービス層) • ただし、常に必要というわけではない • 例えばビジネスロジックがトランザクションスクリプトで実装されている場合 ◦ すでにシステムのパブリックインターフェースを形成する一連のメソッドを公開しているの で、本質的にサービス層

    ◦ こういう場合はサービス層、ビジネスロジック層の一方でいい • 一方でアクティブレコードパターンのように、ビジネスロジックパターンが外部からのオーケスト レーションを必要とする場合は、サービス層が必要となる ◦ サービス層はトランザクションスクリプトパターンを実装し、その上で動作するアクティブレ コードはビジネスロジック層に配置される
  26. Layered Architecture Terminology • 別の用語で使われていることもある 混乱しないように太字を用いる プレゼンテーション層 ユーザインターフェース層 (user interface

    layer) サービス層 アプリケーション層 (application layer) ビジネスロジック層 ドメイン層(domain layer) モデル層(model layer) データアクセス層 インフラストラクチャ層 (infrastructure layer)
  27. Layered Architecture When to Use Layered Architecture • Layered Architectureにおけるビジネスロジック層とデータアクセス層の依存関係はアクティ

    ブレコードパターンやトランザクションスクリプトでビジネスロジックを実装しているシステムに 合う • しかし、ドメインモデルの実装は難しくする • ドメインモデルではビジネスエンティティ (集約, 値オブジェクト)はインフラストラクチャ層に依存 しないし、知識を持たせない ◦ Layered Architectureのトップダウンな依存関係を変えないといけない • layered Architectureでドメインモデルは実装できるが、次の Ports & Adaptersの方が適して いる
  28. Ports & Adapters

  29. Ports & Adapters • Terminology • Dependency Inversion Principle •

    Integration of Infrastructural Components • Variation • When to Use Ports & Adopters
  30. Ports & adapters • ports & adapters architectureはlayered architectureの欠点に対処し、より複雑 なビジネスロジックの実装をするときに適している

    • 両者は非常に似ている • layered architectureをports & adapters architectureにリファクタリングしてみよ う
  31. Ports & Adapters Terminology • プレゼンテーション層とデータアクセス層は外部コンポーネントとの接続 ◦ データベース, 外部サービス, UIフレームワーク

    • これらの実装にはシステムのビジネスロジックは反映しない • このようなインフラストラクチャ的な関心事はまとめてインフラストラクチャ層としま しょう(右図)
  32. Ports & Adapters • しかし伝統的なlayered architectureはビジネスロジック層はインフラ層に依存して いる • 図のようにDIPで依存関係を逆転させる •

    技術的な関心事に挟まれる形にはなるが、ビジネスロジック層が中心の役割になっ た Dependency Inversion Principle • 依存関係逆転の原則(DIP)はビジネ スロジックを実装する高位モジュー ルは、低位モジュールに依存すべき ではないということ
  33. Ports & Adapters Dependency Inversion Principle • 最後にシステムのパブリックインターフェースの正門としてア プリケーション層を追加する •

    layered architectureのサービス層同様、システムによって 公開されているオペレーションを表現し、それらを実行するシ ステムのビジネスロジックをオーケストレーションする • ドメインモデルやイベントソースドドメインモデルパターンに必 要な、何にも依存しないビジネスロジック層が実現した
  34. Ports & Adapters Integration of Infrastructural Components • 核となる目的はシステムのビジネスロジックとインフラストラクチャコンポーネントを 分離させること

    • インフラストラクチャコンポーネントを直接参照したり呼んだりする代わりに「ポート」 をビジネスロジックに定義する • インフラストラクチャコンポーネントは「アダプタ」を実装する ◦ アダプタはポートインターフェースの実装 ◦ dependency injectionかbootstrappingで
  35. Ports & Adapters Integration of Infrastructural Components • メッセージバスのport, adapterの実装

    • ビジネスロジック層でインターフェース定義 し、インフラ層で実装する
  36. Ports & Adapters Variants(変異体) • ports & adaptersアーキテクチャはhexagonal architecture, onion

    architecture, clean architectureとしても知られている • これら全ては同じ設計原則に基づいており、コンポーネントやコンポーネント間の関 係は同じ • layered architectureの場合は用語が異なるかもしれない • コンセプトから違うと勘違いしないためにもユビキタス言語を使おう アプリケーション層 サービス層, ユースケース層 ビジネスロジック層 ドメイン層, コア層
  37. Ports & Adapters When to Use Ports & Adapters •

    ビジネスロジックを全ての技術的関心から切り離すことで、ドメインモデルパターン で実装されたビジネスロジックに完璧にフィットする
  38. Command-Query Responsibility Segregation

  39. Command-Query Responsibility Segregation • Polyglot Modeling • Inplementation • Projecting

    Read Models • Challenges • Model Segregation • When to Use CQRS?
  40. Command-Query Responsibility Segregation • ports & adaptersと同じ構造化の原則に基づいている ◦ ビジネスロジックとインフラストラクチャの関心事 •

    違うのはシステムのデータ管理の方法 ◦ システムのデータを複数の永続モデルで表現する • なぜこういった解決法なのか、どのように実装するかをみていく
  41. Command-Query Responsibility Segregation Polyglot Modeling(多言語モデリング) • システムの全てのニーズに対応するには単一のビジネスドメインモデルでは難しいことが 多い • 7章のonline

    transaction processing(OLTP), online analytical processing(OLAP)はシ ステムのデータについて異なる表現が必要な場合があった • ポリグロット・パーシステンスの概念 ◦ 完璧なデータベースは存在しない . (Greg Young) ◦ すべてのデータベースは欠陥があり、スケール、一貫性、クエリモデルのニーズのバランスを取らなければなら ない ◦ ポリグロット永続化モデル ▪ 例えば、あるシステムでは、運用データベースとしてドキュメントストア、分析・レポート用としてカラムスト ア、堅牢な検索機能を実装するためにサーチエンジンを使用したりする
  42. Command-Query Responsibility Segregation Polyglot Modeling(多言語モデリング) • CQRSはイベントソーシングに関係がある ◦ もともとイベントソースドモデルの限定的なクエリに対処するため ◦

    一度に1集約のイベントしかクエリできない • CQRSはプロジェクションモデルを実体化し柔軟なクエリを可能にする
  43. Command-Query Responsibility Segregation Inplementation/コマンド実行モデル • システムの状態を更新するオペレーションを行うモデル ◦ ビジネスロジック、ルールのバリデーション、不変量に使われる ◦ システムのソースの強整合性データ

    (全ての更新が含まれ、最新の状態 )を表す唯一のモデル ◦ ビジネスエンティティの強整合性のデータを読みとることができ、楽観的並行性制御をサポートしな くてはならない
  44. Command-Query Responsibility Segregation Inplementation/読み取りモデル • プリキャッシュされたプロジェクション(射影)のこと • データベース、フラットファイル、インメモリキャッシュに配置できる • 適切にread

    modelを実装すれば、プロジェクションは全て消去しても再生成できる • モデル化するときには見据えられなかったようなプロジェクションも後から追加でき る • 読み取り専用
  45. Command-Query Responsibility Segregation Projecting Read Models • 読み取りモデルはコマンド実行モデルの変 更を反映しないといけない •

    同期的プロジェクションと非同期プロジェクションをみていく
  46. Command-Query Responsibility Segregation Projecting Read Models/同期プロジェクション • キャッチアップサブスクリプションモデルを通して更新をOLTPデータにフェッチする ◦ プロジェクションエンジンの動作

    ▪ 最後に処理されたチェックポイント以降に追加・更新されたレコードを OLTP データベースに 問い合わせる ▪ 得られた更新されたデータを使って、システムの読み取りモデルを再生成 /更新する ▪ 最後に処理されたレコードのチェックポイントを保持する
  47. Command-Query Responsibility Segregation Projecting Read Models/同期プロジェクション

  48. Command-Query Responsibility Segregation Projecting Read Models/同期プロジェクション • キャッチアップサブスクリプションを機能させるには ◦ コマンド実行モデルは、追加または更新されたすべてのデータベースレコードにチェックポイントを

    記録する必要がある ◦ ストレージ機構は、チェックポイントに基づくレコードの問い合わせをサポートする必要がある
  49. Command-Query Responsibility Segregation Projecting Read Models/同期プロジェクション • チェックポイントはSQLサーバのrowversionカラムが使える • そういう機能がない時の解決法

    ◦ カウンタをインクリメントし、変更された各レコードにそれを加える ◦ チェックポイントに基づく問い合わせが一貫した結果を返すようにすることが重要 • プロジェクションの追加/再生成は簡単にできる ◦ 再生成はチェックポイントを 0に戻すだけ
  50. Command-Query Responsibility Segregation Projecting Read Models/非同期プロジェクション • コマンド実行モデルは変更全てをメッセージバスにパブリッシュ • プロジェクションエンジンはメッセージをサブスクライブして読み取りモデルを生成す

  51. Command-Query Responsibility Segregation Challenges • 非同期プロジェクションは、スケーリングや性能面で明らかに有利だが、分散コン ピューティングの課題が多い ◦ メッセージの処理が順番を守らなかったり重複したりすると、一貫性のないデータが読み込まれた モデルに投影される

    • 新しいプロジェクションを追加したり、既存プロジェクションを再生成したりすることが 難しい • 常に同期プロジェクションを実装し、オプションで非同期プロジェクションを実装する ことが望ましい
  52. Command-Query Responsibility Segregation Model Segregation • コマンドは強一貫性コマンド実行モデルに対してのみ動作可能 • クエリはシステムの永続化された状態(読み取りモデル/コマンド実行モデル)を直 接変更することはできない

    • よくある誤解 ◦ コマンドはデータのみを変更でき、データは読み取りモデルを通してのみ表示用として取り出せる ◦ メソッドを実行するコマンドは、決してデータを返してはならない
  53. Command-Query Responsibility Segregation Model Segregation • コマンドはデータを返すべき • 成功したか否か分からないと呼び出し元は失敗に対処できない •

    唯一の制限は、返されるデータが強一貫性モデル(コマンド実行モデル)から発信 されるべきであること
  54. Command-Query Responsibility Segregation When to Use CQRS • 運用の観点ではドメイン駆動設計のコアバリューをサポートする ◦

    目の前のタスクに対して最も効果的なモデルで作業し、ビジネスドメインのモデルを継続的に 改善する • インフラストラクチャの観点では異なる種類のデータベースの強みを活用することができる ◦ コマンド実行モデルの保存にはリレーショナルデータベース ◦ 全文検索には検索インデックス ◦ 高速なデータ検索にはプリレンダリングされたフラットファイル • さらに、CQRSはイベントソースドメインモデルに自然になじむ • イベントソースモデルでは、集合体の状態に基づいてレコードを問い合わせることは不可能だが、 CQRSは状態を問い合わせ可能なデータベースに投影することにより、これを可能にする
  55. Scope

  56. Scope • 境界付けられたコンテキスト全てにハイレベルなアーキテクチャパターンは必要 ない • サブドメイン(コア, サポート, 汎用)を包括する境界付けられたコンテキストの例 が右図 •

    同じタイプのサブドメインでも異なったビジネスロジックやアーキテクチャパター ンが必要かもしれない(10章) ◦ 複数の境界づけられたコンテキストにまたがって一つのパターンに固執すると複雑にな る • Layered Architecture, ports & adapters, CQRSはシステム全 般の構造化の原則ではない
  57. Scope • サブドメインをカプセル化するモジュールの論理的な境界を定義し、それぞれに 適切なツールを使うことが重要 • これらの論理的境界は、より細かい粒度の境界付けられたコンテキストの物理 的境界へとリファクタリングすることが可能(11章) • 目的は、実際のニーズやビジネス戦 略から設計を決めること

    • 水平方向に区切った層構造に加えて 垂直方向の区切りも可能
  58. Conclusion

  59. Conclusion • layered architecture ◦ 技術的な関心事に基づいてコードベースを分解する ◦ ビジネスロジックとデータアクセスの実装を組み合わせるのでアクティブレコードをベースとしたシス テムと親和性が高い •

    ports & adapters ◦ 依存関係を逆転させる ◦ ビジネスロジックを中心に起き、インフラストラクチャへの全ての依存を切り離す ◦ ドメインモデルを用いてビジネスロジックを実装するパターンと相性がいい • CQRS ◦ 同じデータを複数のモデルで表現する ◦ イベントソースドドメインモデルのシステムで使われがち ◦ しかし、複数の永続モデルで動作させたいどんなシステムでも適用化
  60. Exercises

  61. Exercises 1. アクティブレコードパターンでビジネスロジックを実装することができるarchitectural patternsは? a. Layered architecture b. Ports &

    adapters c. CQRS d. aとc
  62. Exercises 1. アクティブレコードパターンでビジネスロジックを実装することができるarchitectural patternsは? a. Layered architecture b. Ports &

    adapters c. CQRS d. aとc
  63. Exercises 2. ビジネスロジックをインフラストラクチャの関心事から切り離すarchitectural patterns は? a. Layered architecture b. Ports

    & adapters c. CQRS d. bとc
  64. Exercises 2. ビジネスロジックをインフラストラクチャの関心事から切り離すarchitectural patterns は? a. Layered architecture b. Ports

    & adapters c. CQRS d. bとc
  65. Exercises 3. ports & adaptersでクラウドプロバイダのマネージドなメッセージバスと接続する必要 があるとき、どのレイヤに実装しますか? a. ビジネスロジック層 b. アプリケーション層

    c. インフラストラクチャ層 d. どこでも
  66. Exercises 3. ports & adaptersでクラウドプロバイダのマネージドなメッセージバスと接続する必要 があるとき、どのレイヤに実装しますか? a. ビジネスロジック層 b. アプリケーション層

    c. インフラストラクチャ層 d. どこでも
  67. Exercises 4. CQRSについて正しい記述はどれでしょうか? a. 非同期プロジェクションはスケールが容易 b. 同期/非同期プロジェクションはどちらも使えるが、同時には使えない c. コマンドは呼び出し元に情報を一切返さない。呼び出し元は確認のためには常に読み取りモデルを 使うべきだ。

    d. コマンドは強整合性モデルから作られた情報ならば返すことができる e. aとd
  68. Exercises 4. CQRSについて正しい記述はどれでしょうか? a. 非同期プロジェクションはスケールが容易 b. 同期/非同期プロジェクションはどちらも使えるが、同時には使えない c. コマンドは呼び出し元に情報を一切返さない。呼び出し元は確認のためには常に読み取りモデルを 使うべきだ。

    d. コマンドは強整合性モデルから作られた情報ならば返すことができる e. aとd
  69. Exercises 5. CQRSは、同じビジネスオブジェクトを複数の永続モデルで表現できるため、同じ境界 付けられたコンテキスト内で複数のモデルを扱うことができるようになる。境界付けられ たコンテキストはモデル境界を表すということに矛盾していないか?

  70. Exercises 5. CQRSは、同じビジネスオブジェクトを複数の永続モデルで表現できるため、同じ境界 付けられたコンテキスト内で複数のモデルを扱うことができるようになる。境界付けられ たコンテキストはモデル境界を表すということに矛盾していないか? 矛盾しない。複数モデルのうちコマンド実行モデルのみが正しいモデルとして扱われる から。読み取りモデルはプロジェクション(投影)