イミュータブルでゆこう に行ってきた #現場から学ぶモデル駆動設計

イミュータブルでゆこう に参加しました。簡単に所感をまとめます。

modeling-how-to-learn.connpass.com

所感

イベントとリソースを区別したりイベント (コト) に注目するというのは、頭では分かっていても実際に設計するときにちゃんと実践できるだろうか...。どうしてもヒトやモノというか、UI やテーブル設計に意識が向きがちなので、このあたりを転換できるようにしたいです。

最近、イベントデータを集約する処理でレイテンシが悪化して問題になる事例があった (というか自分が作り込んだ...) ので、スナップショットを取る方法は試してみたいところ。

以下、メモから抜粋。

イミュータブルデータモデルの極意

www.slideshare.net

  • 場合分けを形式知になっていない
  • data, inform, information
    • データは事実の集合
    • データだけでは意味をなさない
    • 選択/加工して知識を取り出す > information
  • data > event, resource
  • event (コト)
    • 日時属性を持つ
    • 時系列の並びが重要 (非対称性)
    • 例) 会員
  • resource (モノ)
    • 日時属性は持たない
    • ライフサイクルに伴って属性が変化する
    • 属性が変化しても identity は変わらない
    • 例) 会員登録
  • イベントによってリソースが生成/更新/削除される
  • イベントを永続化するかどうかは業務設計による
  • イベント-リソース
    • イベントの7W3Hがリソースと関連を持つ
  • リソース-リソース
    • 親子関係/依存関係
    • ライフサイクルが同じかどうか
    • 依存/非依存は業務の制約次第
  • イベント-イベント
    • 時系列, 並びが変わると関係が変わる
    • イベントデータを更新しないように設計する
    • 例) 注文-請求
      • 注文イベント生成前に請求イベントは存在しない
      • 注文イベントに請求の属性は持たせない
  • サブタイプ
    • 共通の性質をスーパータイプに持たせる
    • 差分の性質をサブタイプに持たせる
    • リソースのサブタイプは区分で分類する (区分をスーパータイプに持たせる)
  • イベントが親子構造を持つケース
    • 親子のイベントをまとめてイベントとする
    • 子のイベントに後続のイベントが関連付くこともある
    • 子のイベントが日時属性を持っていなくてもイベントとして扱う
  • 一連のイベントのステータス
    • ロングタームイベント
  • リソース同士を関連付けるイベント
    • リソース間の関連と、それに関するイベントは区別する
    • 例) 所属, 配属イベント
  • どのイベントを記録として残すか
    • リソースの生成/変更/削除 > 変更履歴
    • イベント発生から次のイベントが生成される > 業務フロー
    • 非依存のリソースの関連付け/解消 > 業務イベント, 操作履歴
  • お金を生むもの, 記録がないとお金を失うリスクがあるもの
  • イベントは変更してはならない (事実が失われてしまうので)

あとで読む

ドメイン駆動設計とイミュータブルデータモデルの素敵な関係

  • 必ずイミュータブルにする
  • 閉じた操作
    • 引数の型と戻り値の型はそのクラスの型に閉じる
  • withメソッド (setterの代わり)
    • 不変なオブジェクトを元に別インスタンスを作成して返す
    • 部分的な変更
  • イベントリポジトリ/集約ファクトリ
    • 事実の記録と集約の構築は非対称
    • 集約は永続化しない
    • 集約を変更する際は先に事実を記録してから集約インスタンスを生成する
    • 同じ事実からは同じ結果/集約が返る (一貫性)

ドメインイベントの観点から再考するソフトウェア設計

  • ドメインイベントは過去に起きたドメイン上の出来事
  • Event Sourcing に限らない
  • ドメインイベント = 事実
  • 事実 = 事態 + 成立
  • コトに注目する
    • コトはヒト/モノ同士を関連付ける
    • 時間軸に沿って前後関係を持つ
  • ヒト/モノから分析しない
  • コトを手掛かりに分析する
  • Event Sourcing
    • イベントからステートを作り出す
    • applyEvent
  • イベントは追記のみ (更新はしない)
    • ロックがないのでスケールしやすい
  • 非同期連携しやすい
  • 大量イベントをリプレイするとレイテンシが悪化する
    • 一定のタイミングでスナップショットを取る
  • Event Storming
    • コトからモノを探索する
    • イベントはコマンドが受理されたときに生成される
  • イベントのデータストアは RDB である必要はない
    • NoSQL とか...
  • Akka-ES モデル
    • 集約アクター内のオブジェクトグラフがデータソースとなる
    • シャーディング

その他

  • デフォルトは不変
  • 可変は局所的にする
  • イミュータブルはテストしやすい
  • ビジネスロジックでは戻り値を返さないことはない
  • void を使うのは外部の書き込みくらい
  • NOT NULL, 追記のみ (UPDATEしない)