第14章:ドメインイベントの正体:起きた事実を表す🔔🕒
この章のゴール🎯✨
この章が終わると、次の3つがスッキリ言えるようになります🙂💡
- ドメインイベントって何?(一言で!)🗣️
- 「イベントっぽいけど違うやつ」を見分けられる👀
- ミニEC(注文→支払い→発送)で、イベント候補を自力で5個以上出せる🛒💳📦
14.3 ドメインイベントの構成要素📦🧩

ドメインイベントには、最低限以下の情報を含めます。 ドメインイベント(Domain Event)= ドメイン(業務)の中で起きた、意味のある“事実” 🔔🕒 「アプリにとって都合がいい通知」じゃなくて、現実(業務)で起きたことの記録って感覚です🙂✨
Martin Fowlerさんの説明でも、ドメインイベントは「何かが起きた」ことを表すデータ構造として語られます。 (martinfowler.com) DDDのリファレンス(Eric Evans系)でも、ドメインイベントは「過去の出来事の記録」で、基本的に不変(immutable)で、発生時刻や関係するエンティティの識別子などを含む、とされています。 (Domain Language)
「イベント」って言っても、いろいろあるよね🤔💭
ここで言うドメインイベントは、こういう気持ち👇
- ✅ 業務的に意味がある(人間が読んで「そうだね」ってなる)🙂
- ✅ 過去形の事実(もう起きた)🕒
- ✅ 基本は変えない(歴史を書き換えない)🧊
- ✅ ドメイン語彙で書く(SavedToDb みたいな技術語彙じゃない)🙅♀️
例でつかむ:ミニECだとこうなる🛒✨
事実(ドメインイベント)になりやすい例🔔
- OrderPlaced(注文が確定した)🛒✅
- PaymentCompleted(支払いが完了した)💳✅
- OrderCancelled(注文がキャンセルされた)❌
- ShipmentCreated(発送が作成された)📦
- ShipmentDelivered(配達完了した)🏠✅
これ、全部 「起きた」 だよね🙂🕒
逆に、ドメインイベントじゃない(または危ない)例⚠️🙅♀️
① 命令(コマンド)混入タイプ📣➡️
- SendPaymentEmail(支払いメール送って!)📧💨
- ShipOrder(発送して!)🚚
これ、“やれ” だから命令です。 イベントは “やった(起きた)” じゃないとブレやすいよ〜🙂
② 技術都合の出来事タイプ🔧
- OrderSavedToDatabase(DBに保存された)💾
- CacheInvalidated(キャッシュ消した)🧹
これは技術的には起きた事実だけど、業務の意味として薄いことが多いです😵💫 (※運用や監視で必要になることはあるけど、それは“ドメインイベント”とは分けて考えるのが安全🙂)
③ 未来や仮定が混ざるタイプ🔮
- PaymentWillBeCompleted(支払いが完了する予定)🌀
- ShipmentMayBeCreated(発送されるかも)🌫️
イベントは「確定した過去」の記録が基本だよ🕒✅
ドメインイベントは「通知」じゃなく「事実の表現」🧠🔔
ここ、超大事ポイント💡
イベントを使うと、結果として 「メール送る」「ポイント付与する」みたいな処理を“後から”ぶら下げられるようになります🎁📧 でも、イベントの本体はあくまで…
- ✅ その瞬間、業務で何が起きたか
- ✅ それを表す名前と情報
なんだよね🙂✨
ドメインイベントの“最低限セット”って何?📦✨
DDD Referenceの説明をイメージすると、ドメインイベントにはだいたいこれが入ります👇 (Domain Language)
- イベント名(例:OrderPaid)📝
- いつ起きたか(OccurredAt / Timestamp)🕒
- 誰(どの集約)で起きたか(AggregateId / EntityId)🪪
- 必要なら、重要な値(例:支払い金額、決済手段など“業務上の意味があるもの”)💰
逆に入れない方がいいのは👇🙅♀️
- DbContext / HttpContext / Repository みたいな“仕組みの部品”🔧
- 巨大なオブジェクト丸ごと(太りやすい🐘💦)
C#での表現:イベントは“不変なデータ”が相性よし🧊💎
C#では「不変なデータ」を作るのが得意なので、イベントと相性がいいです🙂 (2026年1月時点では .NET 10 / C# 14 が最新の安定ラインとして扱えます。 (gihyo.jp))
たとえば「支払い完了」を、イベントとして“記録”するだけの形👇
public interface IDomainEvent
{
DateTimeOffset OccurredAt { get; }
}
public sealed record OrderPaid(
Guid OrderId,
decimal PaidAmount,
DateTimeOffset OccurredAt
) : IDomainEvent;
ポイントはここ💕
recordで データっぽく する📦- 作ったら基本変えない(=事実の記録)🧊
- “OrderId と OccurredAt” みたいな 意味ある最小限 を入れる✂️✨
「事実っぽさ」チェックリスト✅🔍
イベント候補が出てきたら、これで判定すると安定します🙂✨
- ✅ 過去形で言える?(〜した / 〜された)🕒
- ✅ 業務の人が聞いて意味わかる?(技術用語だらけじゃない?)🗣️
- ✅ 起きたら取り消せない“歴史”っぽい?(後から編集したくならない?)🧊
- ✅ この出来事で、ドメイン上の状態が変わった?(意味のある変化?)🔁
やってみよう🛠️:ミニECのイベント候補を5つ出す💡🛒
ミニECの流れを思い出してね👇 注文(Order)➡️ 支払い(Payment)➡️ 発送(Shipment)
次の「業務上の出来事」を、過去形のイベント名にしてみよう🙂✍️
お題🎮
- 注文が確定した
- 支払いが完了した
- 支払いが失敗した
- 発送が作成された
- 配達が完了した
例(答えの形)✨
- OrderPlaced
- PaymentCompleted
- PaymentFailed
- ShipmentCreated
- ShipmentDelivered
※ ここでのコツは「技術」じゃなくて「業務」で言うことだよ🙂💕
よくあるミスあるある💥(先に潰そう🙂🧯)
ミス①:イベントを“処理のスイッチ”にしちゃう🎛️😵
「メール送信のためにイベント作る」だけだと、名前がズレがち💦 ✅ まずは事実(例:PaymentCompleted)を置いて、 その後で「メール送信」などを“反応”として付けるのがキレイ🙂✨
ミス②:イベントに何でも詰め込む📦🐘
「あれもこれも必要かも…」で巨大化しがち! ✅ まずは ID+時刻+必要最小限 から始めるのが安全✂️✨
ミス③:イベント名が“内部実装”になる🔧🌀
OrderSavedToDb みたいになると、ドメインから離れていきます🙅♀️
✅ “ユーザーや業務が見る出来事” に寄せる🙂
AI相棒に頼むと超ラク🤖✨(でも判断は自分🎯)
イベント候補出しや命名のたたき台は、AIが得意です🙂💕
使えるお願い例📝
- 「ミニECで起きる“業務的に意味のある過去形イベント”を10個、短い名前で提案して」🔔
- 「このユースケースを“事実(イベント)”の列に直して」✍️
- 「このイベント名、技術寄りじゃない?ドメイン語彙に直して」🧼
⚠️ ただし、**「それが本当に業務的に意味があるか」**は人間が決めるのが大事だよ🙂🎯
14.1 ドメインイベントって何?🔔✨

ドメインイベントは、ドメイン内で**「何かが起きた」という事実**を表すオブジェクトです。
-
目的は通知じゃなく、まず 事実をちゃんと表現すること 📣✅
-
迷ったら
- 過去形?🕒
- 業務の言葉?🗣️
- 不変の記録?🧊 でチェック🙂✅
ミニクイズ🎓🎮(サクッと確認)
次のうち「ドメインイベントっぽい」のはどれ?(複数あり)🙂
- SendReceiptEmail 📧
- OrderPaid 💳✅
- OrderSavedToDatabase 💾
- ShipmentDelivered 📦🏠✅
- RecalculateTotalAmount 🔁
✅ それっぽい:2 と 4 (1と5は命令、3は技術都合になりやすい💡)