第23章:粒度の基本(小さすぎvs大きすぎ)📏
この章のゴール🎯
- Bounded Context(BC)の「大きさ(粒度)」をどう決めるかが分かる😊
- **小さすぎ・大きすぎの“地獄サイン”**を見抜ける👀⚠️
- ミニEC(注文・在庫・配送・請求)を例に、**“ちょうどいい仮置き”**ができる🛒✨
1) 粒度ってなに?🍰📏

BCの粒度=「この“会話(言葉)とモデル”が、どこまで同じ意味で通じる範囲にするか」だよ〜🗣️✨
ポイントはこれ👇
- BCは**“ひとつの業務能力(business capability)”**を担当するのが基本の考え方💪
- その代わり、BCをまたぐときは **契約(API/イベント/DTO)**でつながる📨
これは Microsoft のガイドでも、サービス(やモジュール)が1つの業務能力を、BCの中で自律的に実装するイメージとして説明されてるよ。(Microsoft Learn)
2) 「大きすぎBC」あるある💥(衝突地獄)
BCがデカすぎると、同じ言葉が同じ意味で保てなくなるのがしんどいポイント😵💫
大きすぎのサイン🚨
- 「注文」「顧客」「住所」「金額」などの言葉が、部署や機能ごとに意味ズレる🌀
Customerが 会員でもあり、請求先でもあり、配送先でもあり…万能化💣- 仕様変更が入るたびに、別領域まで巻き込んで改修が雪崩れる🌨️
さらに、人が増えるほど 同じBC内でモデルと言葉が分裂しやすい(そして統一が辛い)って話も有名👥💥 Eric Evans の DDDリファレンスでは、BC内で人数が増えるとモデルが断片化しやすく、でも細かくしすぎると統合と一貫性を失う、と注意してるよ。(Domain Language)
3) 「小さすぎBC」あるある😵💫(連携地獄)
逆に、BCを細かくしすぎると今度は “つなぐ作業” が主役になるよ〜📡💦
小さすぎのサイン🚨
- ちょっとしたユースケース(例:注文確定)に 3〜5個のBCが会話してる📞📞📞
- 連携のたびに DTO が増殖、イベントが増殖、調整が増殖📦🧨
- 「結局どこが責任持つの?」が毎回あいまいになる🤷♀️
DDDの考え方でも、細かく分けすぎると 統合や一貫性という“おいしい部分”が失われるって注意があるよ。(Domain Language)
4) じゃあ「ちょうどいい粒度」ってどう決めるの?🧭✨
コツは “1個のBCで、会話がスムーズに完結するか” を見ることだよ💬🚀
判断軸はこの5つ(超実戦)✅
-
**言葉が一貫してる?**🗣️
- そのBCの中で「注文」がブレない?(状態や金額の定義が同じ?)
-
**責任が一貫してる?**🎒
- “何のためのモデル?”が1行で言える?(例:受注を正しく管理する、在庫を正しく引き当てる)
-
**変更の波が同じ?**🌊
- 割引・送料・在庫ルール・請求ルール…変わり方が違うなら分ける候補✂️
-
**同時に正しくしたい範囲(トランザクション感覚)**🔁
- 「ここは同時に確定したい」がBCをまたぐなら、粒度を見直すサイン🧠
-
**連携の重さ(会話の回数)**📞
- 1ユースケースで、BC間の往復が多すぎるなら“小さすぎ”疑い😵💫
そして、Vaughn Vernon は「BCは、その業務領域のユビキタス言語を全部含めるのに十分大きく、でもそれ以上は大きくしない」的な考え方を述べてるよ。(Dokumen)
5) ミニECで「粒度の仮置き」をやってみよう🛒✨
まずは “会話のまとまり” で仮置きしてOK👌(最初から完璧はムリ!)
例として、こういう分け方が自然になりやすい👇
- 受注管理(Order Management):注文受付、注文状態、注文合計(注文視点)📦
- 在庫管理(Inventory):引当、在庫数、欠品、入荷📦📉
- 配送管理(Shipping/Fulfillment):出荷、配送先、追跡番号🚚📮
- 請求/決済(Billing/Payments):請求書、支払い、返金💳🧾
ここで大事なのは、同じ「住所」でも意味が違っていいってこと🏠✨
- 受注の住所:注文時点のスナップショット(後から変わっても注文は変えない)📦
- 配送の住所:配送ラベルとして必要な項目やフォーマットが主役🚚
6) C#で“境界の違い”を見える化するミニ例💻✨
「同名だけど意味が違う」を namespace で分けると、衝突が目で見えるよ👀
namespace ECommerce.OrderManagement
{
// 注文のための住所(注文時点のスナップショット)
public record OrderAddress(string PostalCode, string Prefecture, string City, string Line1);
}
namespace ECommerce.Shipping
{
// 配送のための住所(配送ラベル向けに項目が違ってもOK)
public record ShippingAddress(string PostalCode, string FullName, string AddressLine, string PhoneNumber);
}
この時点で「住所って1個に統一すべきでは?」って思ったら、それは良い疑問🤔✨ でも “統一すると会話が混ざる” なら、分けた方が安全なことが多いよ(混ぜると後で爆発しがち💥)。(Domain Language)
7) 粒度ミスを直す「方向」だけ覚えよう🔧✨
- 大きすぎっぽい → **言葉の衝突点(注文/顧客/金額/住所など)**から切る✂️
- 小さすぎっぽい → **1ユースケース内の往復(連携回数)**が多いところをまとめる🧲
「BCをどう分けるか」は、最終的には 境界同士の契約をどう作るか(API/イベント/DTO)にも直結するよ。(Microsoft Learn)
8) ミニ演習📝✨(15〜25分)
演習1:イベントを“会話のまとまり”で分ける🌩️🧺
次のイベントを、まずは 3〜5グループに分けてみてね👇
- 注文が作成された
- 支払いが承認された
- 在庫が引き当てられた
- 欠品が検出された
- 出荷が作成された
- 追跡番号が発行された
- 請求書が発行された
- 返金が確定した
👉 グループ名(仮)を付けて、「そのグループの目的」を1行で書く✍️✨
演習2:小さすぎチェック📞😵💫
「注文確定」ユースケースで、BC間の呼び出しが 7回発生してるとする📞📞📞 👉 “まとめるならどことどこ?”を1案出して、理由を一言で💡
演習3:大きすぎチェック💥🌀
Order の中に、出荷・請求・在庫の状態が全部入り、ifが増え続けてる💣
👉 “分けるならどこから?”を 衝突しやすい単語(住所/金額/顧客/状態など)で指定してね🔍
9) つまずきポイント集🧩(あるある!)
-
「最初から正解のBC分割を当てたい」→ 当てなくてOK🙆♀️ まずは仮置きして、**衝突(大きすぎ)or 往復(小さすぎ)**で育てる🌱
-
「共通にした方がDRYでは?」→ DRYより“意味の一貫性”が優先な場面があるよ📌 “同じ形のデータ”でも“責任”が違えば別物になりやすい🧠✨
-
「BC=マイクロサービス?」→ 近いけど、まずは 境界を設計として決めるのが先🗺️ サービス化は後からでもできる👌(境界が曖昧なまま分散すると余計しんどい💦)(Microsoft Learn)
10) この章の「お助けAIプロンプト」🤖✨
- 「このイベント一覧を、会話のまとまりで3〜5グループに分けて。各グループの目的も1行で」🌩️
- 「“大きすぎBC”のサインを、今回のミニEC例で具体化して列挙して」💥
- 「“小さすぎBC”のサインを、連携回数・データ重複・運用コストの観点で列挙して」📞
- 「この2つの境界案を比較して、結合度/凝集度/変更の波/トランザクション観点で短く評価して」⚖️
- 「“住所”を Order と Shipping で分けるべきか、責任の違いで説明して」🏠
まとめ🎀✨
- 大きすぎ:言葉が衝突してモデルが混ざる💥
- 小さすぎ:連携が増えて“つなぐ作業”が主役になる😵💫
- まずは 会話のまとまりで仮置き → **衝突(大きすぎ)/往復(小さすぎ)**で調整🔁✨