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

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. Overview • Business Logic Versus Architectural Patterns • Layered Architecture

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

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

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

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

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

    の動作のトリガー全てを指す ◦ Graphical user interface (GUI) ◦ Command-line interface (CLI) ◦ 他システムと接続する API ◦ メッセージブローカーでのイベントのサブスクリプション ◦ 外に発信するイベントのメッセージトピック
  7. Layered Architecture データアクセス層 • 永続化メカニズムへのアクセスを行う • 本来はデータベースへの参照 • PLと同様にモダンなシステムではスコープが広がっている •

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

    Google Cloud Strage) ◦ システムの内部で用いられるメッセージバス • 3つ目は、様々な外部の情報プロバイダと接続すること ◦ 外部システムが提供する APIやクラウドベンダのマネージドサービスなど ▪ 言語翻訳 ▪ 株式市場データ ▪ 音声転写
  9. Layered Architecture Variation(サービス層) • サービス層はプレゼンテーション層とビジネ スロジック層の中継 • 右のコードのMVCコントローラはプレゼン テーション層にあり新規ユーザを作るエンド ポイントを公開している

    • ユーザのアクティブレコードオブジェクトを 使って新しいインスタンスを作り、セーブして いる • 更に、エラーの際に適したレスポンスを作る ようにデータベーストランザクションを貼って いる
  10. Layered Architecture Variation(サービス層) • 右図のメソッド(CreateCampaign …)は 全てシステムのパブリックインターフェー ス • かつ、プレゼンテーションに関する実装に

    ついては隠蔽されている • プレゼンテーション層の責務は、サービス 層に必要な入力を与え、その応答を呼び 出し元に伝えることに限定される
  11. Layered Architecture Variation(サービス層) • 多くのメリットがある ◦ 同じサービス層を使いまわせる ▪ 例えばGUIとAPIで同じオーケストレーションロジックを複製しなくて済む ◦

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    transaction processing(OLTP), online analytical processing(OLAP)はシ ステムのデータについて異なる表現が必要な場合があった • ポリグロット・パーシステンスの概念 ◦ 完璧なデータベースは存在しない . (Greg Young) ◦ すべてのデータベースは欠陥があり、スケール、一貫性、クエリモデルのニーズのバランスを取らなければなら ない ◦ ポリグロット永続化モデル ▪ 例えば、あるシステムでは、運用データベースとしてドキュメントストア、分析・レポート用としてカラムスト ア、堅牢な検索機能を実装するためにサーチエンジンを使用したりする
  27. Command-Query Responsibility Segregation Inplementation/コマンド実行モデル • システムの状態を更新するオペレーションを行うモデル ◦ ビジネスロジック、ルールのバリデーション、不変量に使われる ◦ システムのソースの強整合性データ

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

    modelを実装すれば、プロジェクションは全て消去しても再生成できる • モデル化するときには見据えられなかったようなプロジェクションも後から追加でき る • 読み取り専用
  29. Command-Query Responsibility Segregation Projecting Read Models/同期プロジェクション • キャッチアップサブスクリプションモデルを通して更新をOLTPデータにフェッチする ◦ プロジェクションエンジンの動作

    ▪ 最後に処理されたチェックポイント以降に追加・更新されたレコードを OLTP データベースに 問い合わせる ▪ 得られた更新されたデータを使って、システムの読み取りモデルを再生成 /更新する ▪ 最後に処理されたレコードのチェックポイントを保持する
  30. Command-Query Responsibility Segregation Projecting Read Models/同期プロジェクション • チェックポイントはSQLサーバのrowversionカラムが使える • そういう機能がない時の解決法

    ◦ カウンタをインクリメントし、変更された各レコードにそれを加える ◦ チェックポイントに基づく問い合わせが一貫した結果を返すようにすることが重要 • プロジェクションの追加/再生成は簡単にできる ◦ 再生成はチェックポイントを 0に戻すだけ
  31. Command-Query Responsibility Segregation Challenges • 非同期プロジェクションは、スケーリングや性能面で明らかに有利だが、分散コン ピューティングの課題が多い ◦ メッセージの処理が順番を守らなかったり重複したりすると、一貫性のないデータが読み込まれた モデルに投影される

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

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

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

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

    同じタイプのサブドメインでも異なったビジネスロジックやアーキテクチャパター ンが必要かもしれない(10章) ◦ 複数の境界づけられたコンテキストにまたがって一つのパターンに固執すると複雑にな る • Layered Architecture, ports & adapters, CQRSはシステム全 般の構造化の原則ではない
  36. Conclusion • layered architecture ◦ 技術的な関心事に基づいてコードベースを分解する ◦ ビジネスロジックとデータアクセスの実装を組み合わせるのでアクティブレコードをベースとしたシス テムと親和性が高い •

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