第02章:まずは超基本:コマンドとイベントの違い📣🤔
2.1 まず結論:2つは「役割」が真逆だよ🧩✨
- Command(コマンド)=命令・依頼📣 「これをやって!」(これから起きてほしいこと)
- Event(イベント)=起きた事実🔔 「これが起きた!」(もう起きたこと・記録したいこと)
特にドメインイベントでは、**イベントは“過去に起きた事実”**として扱うのが大事だよ🕒✨ (Microsoft Learn)
2.2 コマンドとイベントの違い(レストランの例)🍴🍕

「注文する」のと「注文が終わった事実」は、全く別のものです😊 分かりやすくするために、レストランで例えてみましょう!
- Command(コマンド)=命令・依頼📣 「これをやって!」(これから起きてほしいこと)
- Event(イベント)=起きた事実🔔 「これが起きた!」(もう起きたこと・記録したいこと)
🍽️ レストラン編
- Command:「ハンバーガー作ってください!」📣 → 店員さんに“依頼”してる(断られる可能性もある:材料切れとか🥲)
- Event:「ハンバーガーが作られた」🔔 → もう起きた“事実”(取り消せない・言い換えると履歴)🧾
2.3 ライフサイクルの比較⚖️🚀

| 項目 | コマンド(命令) | ドメインイベント(事実) |
✅① 文の形(命令形 vs 過去形)
- Command:「〜して!」(お願い・命令)📣
- Event:「〜した」(事実)🔔 ドメインイベントは「起きたこと」なので 過去形が基本だよ🕒 (Microsoft Learn)
✅② 成功/失敗があるのはどっち?
- Command:失敗することがある(支払いNG、在庫なし、権限なし…⚠️)
- Event:失敗しない(起きた事実を言ってるだけだから)
✅③ 誰が主語?
- Command:「やってほしい」(誰かに仕事を頼む)🧑✈️
- Event:「起きた」(観測・記録)🔍
2.4 ミニECで見る:注文→支払い→発送🛒💳📦
📣 Commandの例(依頼)
- 「支払いを実行して!」(PayOrder)💳
- 「発送して!」(ShipOrder)📦
- 「注文をキャンセルして!」(CancelOrder)🛑
🔔 Eventの例(事実)
- 「支払いが完了した」(OrderPaid)✅
- 「発送された」(OrderShipped)🚚
- 「注文がキャンセルされた」(OrderCanceled)🧾
イベント名は **“過去形 + ドメインの言葉”**が読みやすいよ✨ (Microsoft Learn)
2.5 よくある混同パターン⚠️😵💫(ここ大事!)
❌「イベントなのに命令してる」例
SendPaymentEmail🔥(メール送って=命令じゃん!📣)SaveOrderToDb🔥(DBに保存して=技術詳細だし命令っぽい)
✅「事実」に直すとこうなる
PaymentEmailSent(支払いメールが送信された)📧✅ ※ただし“送る”のは副作用なので、最初は **「支払いが完了した」**みたいな“中心の事実”を優先すると迷いにくいよ🙂OrderPlaced(注文が確定した)🛒✅
2.6 分類ゲーム:命令?それとも事実?🎮✨(10問)
次の10個を Command / Event に分類してみよう✍️🙂
- 「支払いを実行して!」💳
- 「支払いが完了した」✅
- 「注文を確定して!」🛒
- 「注文が確定した」🧾
- 「在庫を引き当てて!」📦
- 「在庫が引き当てられた」📦✅
- 「配送ラベルを作って!」🏷️
- 「配送ラベルが作成された」🏷️✅
- 「注文をキャンセルして!」🛑
- 「注文がキャンセルされた」🧾🛑
✅答え合わせ(サクッと)
- Command:1, 3, 5, 7, 9 📣
- Event:2, 4, 6, 8, 10 🔔
コツ:Eventは「〜された」「〜した」になってることが多いよ🕒✨ (Microsoft Learn)
2.7 C#で超ミニ実装:CommandとEventを“型”で分けよう🧷✨
ポイントはこれ👇
- Command:**「お願い」**なので、入力(何をしたいか)を持つ📣
- Event:**「事実」**なので、起きたこと+最低限の情報を持つ🔔
- Eventは基本 **変更しない(イミュータブル)**が相性いいよ🔒 (download.microsoft.com)
using System;
public interface ICommand { }
public interface IEvent { }
public sealed record PayOrderCommand(Guid OrderId, decimal Amount) : ICommand; // 命令📣
public sealed record OrderPaidEvent(Guid OrderId, decimal Amount, DateTimeOffset OccurredAt) : IEvent; // 事実🔔
public sealed class Order
{
public Guid Id { get; }
public bool IsPaid { get; private set; }
public Order(Guid id) => Id = id;
// ✅ Commandを受けて、ルールを満たせたら状態が変わり、Eventが生まれる✨
public OrderPaidEvent Pay(decimal amount)
{
if (IsPaid) throw new InvalidOperationException("すでに支払い済みだよ😵💫");
if (amount <= 0) throw new ArgumentException("金額が不正だよ⚠️");
IsPaid = true;
return new OrderPaidEvent(
OrderId: Id,
Amount: amount,
OccurredAt: DateTimeOffset.UtcNow
);
}
}
👀 ここで見たい流れ(超重要)🧠✨
- 外から Command が来る📣(例:PayOrderCommand)
- ドメイン(Order)がルールを守って処理する🧩
- 状態が変わったら Event が生まれる🔔(例:OrderPaidEvent)
2.8 命名ミニ練習:良い名前に言い換えよう✍️✨
次を「Commandっぽい? Eventっぽい?」で直してみよう🙂
-
CompletePayment(これ、どっちでも読めちゃう😵💫)- ✅ Command寄りにするなら:
PayOrder/CompletePaymentCommand📣 - ✅ Event寄りにするなら:
PaymentCompleted/OrderPaid🔔
- ✅ Command寄りにするなら:
2.9 AI(Copilot等)を使うときのプロンプト例🤖✨
🧠 命名案を出してもらう(便利!)
- 「“支払い完了”のドメインイベント名を、過去形で10個提案して。ユビキタス言語っぽく短く。」
🔎 混同チェックをさせる(安全!)
- 「この名前はCommand/Eventどっち?理由も。
ShipOrder,OrderShipped,CreateShipmentLabel,ShipmentLabelCreated」
※最後は必ず自分でも確認ね🙂(“命令になってない?” “事実になってる?”)
2.10 チェック✅(この章のゴール)
- Commandは 「やって!」 📣
- Eventは 「起きた!」 🔔(過去形が基本)🕒 (Microsoft Learn)
- 「イベントで命令しない」🙅♀️
- Command → ドメイン処理 → Event の流れが見えたら勝ち🏁✨
2.11 おまけ:最新C#環境のひとことメモ🪄🧩
- C# 14 が最新リリースで、.NET 10 上でサポートされているよ🧠✨ (Microsoft Learn)
- .NET 10 SDKは公式のダウンロードページから入れられるよ🧩 (dotnet.microsoft.com)