1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

イベントソーシングやDDDを学んでいてぶつかった疑問と自分なりの解釈~第一段:イベントソーシングの考え方~

1
Posted at

この記事は自分がイベントソーシングを学んでいて、疑問に思ったことをつらつらと書き、それぞれの疑問に対する自分なりのアンサーを書いたものです。

第1部:イベントソーシングの考え方

1-1. はじめに

最近私はイベントソーシングやDDD(ドメイン駆動設計)の情報を収集しており、学んでいく過程でこんな疑問にぶつかりました。

「全部イベントにすればいいの?」
「単純な更新処理もイベントソーシングするの?」
「境界づけられたコンテキストって、どこで線を引くの?」

本記事では、音楽教室の管理システムを題材に、これらの疑問を設計の視点から解きほぐしていきます。コードよりも「なぜそうするのか」という考え方に焦点を当てていきますね。


1-2. イベントソーシングとは何か

CRUDの状態を保存する vs EventSourcingの出来事を保存する

私は上記のような解釈です。
ざっくり説明すると従来のシステム設計では、データベースに「現在の状態」を保存しますが、イベントソーシングでは「何が起きたか」という出来事を保存します。

  • 【状態を保存する(従来のCRUD)】

┌─────────────────────
│ 口座テーブル     │
│ ID: 001       │
│ 残高: 10,000円      |
│ 更新日: 2024/1/15   │
└─────────────────────


「なぜ10,000円なのか」は追えない
  • 【出来事を保存する(イベントソーシング)】

1. 口座開設された(初期残高: 0円)
2. 入金された(15,000円)
3. 出金された(3,000円)
4. 出金された(2,000円)

→ 出来事を順番に再生すると、残高 10,000円 が導出される
→ 「なぜこうなったか」が全部わかる

イベントソーシングの思想

イベントソーシングは単なる技術選択ではなく、ビジネスをどう捉えるかという設計思想です。

観点 状態保存 イベントソーシング
問い 今どうなっている? 何が起きた?
保存するもの 最新のスナップショット 出来事の履歴
時間軸 現在のみ 過去〜現在
変更の理由 失われる 記録される

どちらが優れているという話ではなく、必要な場面で使い分けるのがポイントです。


1-3. 何をイベントにすべきか

イベントソーシングを学ぶにあたって最初にこんな疑問を抱きました。

全部イベントにすべきなのか?

こちらに関して私はNoだと考えています。
イベントソーシングにはコストがあります。

イベントソーシングのコスト

  • 実装の複雑さが増す
  • イベントストアの管理(スナップショット戦略など)
  • イベントスキーマのバージョニング問題
  • 学習コスト

前提としてコードが複雑になることで、技術負債となるリスクは高まりますし、理解に時間がかかる概念で難易度が高いと考えています。そのため、本当に必要な場所だけに適用するのが現実的であると考えています。

判断の核心:「この出来事に意味があるか?」

判断基準は、次の3つの問いに集約されているという結論に至りました。

① ビジネス上の「出来事」か「状態」か

ドメインエキスパート(ビジネスの専門家)がどう表現するか、に注目。

【出来事として語られる】

「生徒が入会した」
「レッスンが実施された」  
「月謝が支払われた」
「コースが廃止された」

→ 過去形で語られる
→ 「いつ」「なぜ」が重要
→ イベントにすべき
【状態として語られる】

「教室の住所は渋谷区です」
「電話番号は03-xxxx-xxxxです」
「営業時間は10時〜20時です」

→ 現在形で語られる
→ 「今どうなっているか」だけが重要
→ 単純な更新で十分

② この出来事の履歴に、ビジネス上の意味があるか?

「月謝が支払われた」
  → いつ、いくら支払われたかの履歴は監査上必須

⇒ 履歴に価値がある → イベントにすべき
「教室の説明文が更新された」
  → 過去の説明文を参照するシナリオがある?
  → 普通はない

⇒ 履歴に価値がない → 単純な更新で十分

③ 他の誰かが知る必要があるか?

その出来事が、他のコンテキストやシステムに影響を与えるかを考えます。

「レッスンコースが廃止された」

  この事実を知る必要がある人:
  - スケジュール担当 → 予約をキャンセルしなきゃ
  - 経理 → 返金処理が必要
  - 生徒 → 通知しないと

→ 他に波及する → イベントにすべき
「教室の電話番号が変わった」

  この事実を知る必要がある人:
  - ...特にいない。Webサイトに反映されればOK

→ 影響が閉じている → 単純な更新で十分

これらの判断基準は開発者だけで設計するのは不可能なのでドメインエキスパートとの会話は必須となります

  • ドメインエキスパートが「〜された」「〜が起きた」と語るものは、ビジネス上意味のある出来事です。それをイベントとしてモデル化しましょう。イベントストーミングを実施するのが効果的だと考えています。イベントストーミングのやり方に関しては https://www.youtube.com/watch?v=XZ1uOKIYCD0 が参考になります

  • イベントは、コンテキスト間の「共通言語」になります。 他に伝える必要がある出来事をイベントとして明示することで、システム全体の連携がスムーズになります

  • 重要な点としてはイベントの時間軸、時系列がビジネス上意味を持つ場所にだけ適用するのが好ましいのではないかと思います

音楽教室システムでの判断例

具体的に見てみましょう。

操作 イベント? 判断理由
教室の住所変更 他に影響なし、履歴不要
教室の電話番号変更 同上
レッスンコース新設 サービス開始はビジネス上の意思決定
レッスンコース廃止 他に波及する、履歴として重要
レッスン予約 スケジュール履歴として意味がある
レッスン実施記録 指導の証跡、請求の根拠
月謝受領 金銭授受、監査証跡として必須

こうして見ると、ドメインの「コア」に近いほどイベントソーシングの価値が高いことがわかりますね。音楽教室なら「レッスン」と「月謝」がコアで、「教室の住所」は周辺的な情報です。

Vlad Khononov著「ドメイン駆動設計をはじめよう」では以下の図が紹介されています。ドメインを分類する際は中核、一般、補完に分けて行い、最も複雑性と競合優位性が高く変更回数が多い中核ロジックをコアドメインに据えてモデリングしていくという考え方です。
しかし、必ずしもES(イベントソーシング)では複雑さはイベントにする判断基準にはなりません。
イベントソーシングによるモデリングはあくまで先ほどの3つの判断基準に則って判断するのがよいのではないかと考えています。

IMG_8975.jpg

用途 使う図・基準
サブドメイン分類(どこに投資するか) 図(差別化 × 複雑さ
イベント判断(何をイベントにするか) 出来事か × 波及/履歴

DDDのドメインとイベントソーシングのモデリングは

第1部のまとめ

イベントソーシングとは

  • 「現在の状態」ではなく「何が起きたか」を保存する設計思想
  • 出来事を再生することで、任意の時点の状態を導出できる
  • 「なぜこうなったか」の履歴が完全に残る

すべてをイベントにする必要はない

  1. ビジネス上の「出来事」として語られるか?
    a. ドメインエキスパートが過去形で語る → イベント
    b. 現在形で語られる状態 → CRUD

  2. 他の誰かが知る必要があるか?
    a. 波及効果がある → イベント
    b. 影響が閉じている → CRUD

  3. 履歴にビジネス上の意味があるか?
    a. 後から参照するシナリオがある → イベント
    b. 最新状態だけでよい → CRUD

ドメインエキスパートと話そう

  • 判断は開発者だけで行わない
  • 「この履歴は必要ですか?」「これが起きたら誰かに知らせる必要がありますか?」
  • ビジネスの言葉でシステムを設計するのがDDDの核心

DDDのドメインモデルとイベントソーシングのモデリングを同時に扱うにはどうすればいいのか?という疑問がありそちらについても私なりの考えを記事にしたいと思っています。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?