読者です 読者をやめる 読者になる 読者になる

実践ドメイン駆動設計 4.6 メモ

開発 DDD

実践ドメイン駆動設計 (Object Oriented Selection)

実践ドメイン駆動設計 (Object Oriented Selection)

実践ドメイン駆動設計

実践ドメイン駆動設計

コマンドクエリ責務分離(CQRS)

  • 必要なデータを全てリポジトリから取得してユーザに表示するのが、難しいこともある
  • リポジトリだけで解決するのはあまりやりたくない
  • クライアント側で複数リポジトリにアクセスさせ、必要なデータを組み合わせて「データ変換オブジェクト」に格納するという手が一つ
  • リポジトリ上に特別なファインダを用意、一回の問い合わせで各地のデータを取りまとめる
    • どちらもだめならUX設計に妥協が必要 => 人にやさしくないものが出来上がる
  • CQRSというアーキテクチャパターンを導入
    • オブジェクト(コンポーネント)を設計するときの厳しい原則「コマンドとクエリの分離」
    • コマンド => 何らかのアクションを実行する
    • クエリ => 呼び出し元にデータを戻す
      • メソッドが値を戻すのはメソッドが参照透過性(文脈によらず式の値はその構成要素(例えば変数や関数)によってのみ定まるということ参照透過性 - Wikipedia)を持ち、何も副作用を及ぼさない場合だけ
      • メソッドが何らかの値を返すならクエリ
    • これらのどちらか一方しかだめ
  • DDDを採用したときのアーキテクチャパターンとして、なぜ適用するか?
    • CQRSは普通の状態(レポジトリのファインダーメソッド、コマンドとクエリの両方のメソッドを持つ集約)は無視
    • 集約はコマンドメソッドのみ
    • リポジトリはaddメソッドがあって、fromIdのようなクエリメソッドがあるだけ
    • リポジトリからはソレ以外の手段(別のプロパティによる絞りこみ)で集約を取得するこはできない
      • これらのメソッドをモデルから削除して、新たに用意したコマンドモデルに移動する
      • 問い合わせを最適化するようにチューニングしたクエリモデル
  • CQRSの構成要素
    • クライアントとクエリプロセッサ
      • クライアント => WebブラウザやアプリケーションのUI
      • クエリプロセッサ => データベースに対する基本的な問い合わせしか知らない
        * コネクションプーリングもする
        
      • 問い合わせた結果、転送用のフォーマットにシリアライズすること
      • シリアライズは1.とにかくシンプルにする 2. DTOをきちんと組み立ててクライアントに渡す
        * 2.だと複雑性は増す
        
    • クエリモデル
      • 非正規化したデータモデル
      • 表示用のデータだけ扱う
        • データモデルがSQL DBだとすると、表示内容毎にテーブルを用意する(VIEWの意味? テーブルを別々につくる)
        • 例をみると、テーブル自体を分けるので一般ユーザーからはマネージャの情報は見えず、マネージャからも一般ユーザーの情報は見えないとなっている
          • 多分VIEWでいい
    • クライアントからのコマンド実行
      • サーバにコマンドを発行して、集約上の何らかの振る舞いを実行する
      • 振る舞いはコマンドモデルの中にある
      • コマンドのパケットはメソッドの起動処理をシリアライズしたものとなる
      • UIが必要となるデータを取りまとめる必要がある => ユーザ体験の設計には最新の注意を要する
        • 迷わせない
    • コマンドプロセッサ
      • 発行されたコマンドをうけとる
      • 分類方式 => 分類毎にメソッドを宣言、シンプル
      • 専用方式 => ハンドラ毎にひとつの責務
      • メッセージング方式 => 非同期。便利だが、設計が複雑
      • 個々のハンドラが他のハンドラに依存しないようにする