本章の方針
DDDの戦術的パターンは8個あるが、全てを同時に導入する必要はない。むしろ「すべて入れる」ことを目的にすると、確実に失敗する。本章では、8パターンの関係を一枚の地図に配置し、費用対効果の観点で優先順位 をつける。
この地図は以降の章の見取り図になる。
戦略的DDD vs 戦術的DDD
まず、戦略的と戦術的を明確に分離する。両者は目的もスコープも異なる。
| 区分 | 目的 | 主な道具 | スコープ |
|---|---|---|---|
| 戦略的DDD | どこにコードを書くかの地図を作る | ユビキタス言語・境界づけられたコンテキスト・Context Map | 組織・サービス境界 |
| 戦術的DDD | 1つのコンテキスト内でモデルを実装する | Value Object・Entity・集約・Domain Service・Application Service・Repository・Factory・Domain Events | コードベース内 |
戦略的DDDは「どこに書くか」、戦術的DDDは「どう書くか」を扱う。混同すると議論が噛み合わない。
よくある誤解:
❌ 「戦術的DDDを導入すれば、自然にマイクロサービスに移行できる」
→ マイクロサービス化は戦略的DDDの領域。Value Objectを増やしてもサービスは分割されない。
❌ 「境界づけられたコンテキストさえ切れば、DDDをやっていると言える」
→ 戦略的な境界だけで、内部実装は従来通りという状態は「DDD-lite」と呼ばれる。
これ自体は悪くないが、「戦術的DDDをやっている」とは言えない。
本記事は 戦術的DDDだけ を扱う。境界づけられたコンテキストの切り方は姉妹記事 EvansとVernonで学ぶDDD に譲る。
8つの戦術的パターン
戦術的DDDのパターンは以下の8つだ。
graph TD
subgraph BuildingBlocks["ドメイン層の構成要素"]
VO[Value Object<br/>値オブジェクト]
E[Entity<br/>エンティティ]
A[Aggregate<br/>集約]
DS[Domain Service<br/>ドメインサービス]
DE[Domain Events<br/>ドメインイベント]
F[Factory<br/>ファクトリ]
end
subgraph Infra["境界を守る要素"]
AS[Application Service<br/>アプリケーションサービス]
R[Repository<br/>リポジトリ]
end
VO -.構成要素.-> E
VO -.構成要素.-> A
E -.集まり.-> A
A -.発火.-> DE
F -.生成.-> A
DS -.操作.-> A
AS -.調整.-> A
AS -.永続化.-> R
R -.復元.-> A
この図の読み方を補足する。
- Value Object・Entity・集約・Domain Service・Domain Events・Factory はドメイン層に配置される。ビジネスルールを表現する
- Application Service・Repository はドメイン層と外部(DB・API・UI)の境界を守る
- Value Object は Entity の部品、Entity の集まりが Aggregate、集約は Domain Events を発火させる、という階層関係がある
費用対効果マトリクス
この8パターンは「導入コストの低さ」と「得られるリターン」で評価すると、明確に序列がある。全部入れる必要はないことが、この地図から見えてくる。
quadrantChart
title 戦術的DDDパターンの費用対効果
x-axis "導入コスト小" --> "導入コスト大"
y-axis "リターン小" --> "リターン大"
quadrant-1 "優先導入"
quadrant-2 "即導入"
quadrant-3 "判断次第"
quadrant-4 "慎重判断"
"Value Object": [0.15, 0.85]
"Domain Events": [0.45, 0.80]
"Application Service": [0.25, 0.55]
"Repository": [0.40, 0.45]
"Entity": [0.35, 0.50]
"Factory": [0.20, 0.35]
"Domain Service": [0.50, 0.40]
"Aggregate": [0.85, 0.75]
この図が示す序列を筆者の体験に基づいて言語化すると以下のとおりだ。
即導入カテゴリ(左上)
- Value Object:導入コストが最も低く、プリミティブ型病の治癒効果が極めて高い
- Application Service:トランザクション境界を明示でき、テストの書きやすさが劇的に向上する
- Factory:集約を複雑な初期化ロジックから守る。コストは低い
優先導入カテゴリ(右上)
- Domain Events:非同期処理・監査ログ・通知を疎結合化する強力な武器。ただし運用観測性が要求される
- Aggregate:最も難しく最も議論的だが、正しく使えばビジネスルールを集約できる。ただしコストが最も高い
判断次第カテゴリ(左下)
- Entity:ID を持つオブジェクトを明確化する。しかし実態は「識別子付きのクラス」であり、過度な概念化は不要
- Repository:ORMが十分強力な現代(2026年)では、薄いラッパーで終わるケースが多い
慎重判断カテゴリ(右下)
- Domain Service:「どこに置けばいいか分からないロジック」の受け皿になりがち。「なんでもServiceアンチパターン」の温床
この順序は本記事の章立ての根拠でもある。
この地図に対する反論
この優先順位付けには当然反論がある。代表的なものを3つ挙げ、本記事の立場を明示する。
反論1:「Value Object から入ると、全てをVO化したくなる副作用がある」
対する立場:正しい。Ch.3で「VO化すべきではないもの」を明示する。
反論2:「Aggregate を慎重扱いすると、DDDを骨抜きにする」
対する立場:Aggregate の重要性は認めるが、実務で最も失敗を生みやすいのも事実。「小さく始めて必要になったら導入する」 を推奨する。Ch.5で詳細に扱う。
反論3:「Domain Service を慎重扱いすると、本物の”ドメインの振る舞い”が書けなくなる」
対する立場:Domain Service が必要な場面は実在する(Ch.6で扱う)。ただし実務では「とりあえずService」に流れる傾向がある。まずは Value Object と Entity にロジックを寄せることを試し、それでも無理なときだけ Domain Service を導入する、という順序を推奨する。
段階的導入の推奨順序
筆者の実務経験に基づく推奨順序は以下のとおり。
Phase 1(最初の2〜4週間)
1. Value Object を導入する
→ プリミティブ型の混同バグを潰す
2. Application Service を導入する
→ トランザクション境界とテストの入口を作る
Phase 2(次の1〜2ヶ月)
3. Entity と Repository を導入する
→ IDを持つオブジェクトの永続化境界を切る
4. Factory を導入する(必要に応じて)
→ 初期化ロジックが複雑な箇所のみ
Phase 3(モデルが成熟してから)
5. Aggregate を導入する
→ 一貫性ルールが明確になってから境界を決める
6. Domain Events を導入する
→ 集約間の依存が見えてきてから
Phase 4(最後の手段)
7. Domain Service を導入する
→ Value Object にも Entity にも置けないロジックだけ
この順序は 「モデルを書きながら境界が見えてくる」 という前提に立っている。いきなり Aggregate から設計を始めると、多くの場合は過剰な境界を引いてしまう。
本章のまとめ
・戦術的DDDは8パターンある
・全てを同時に導入する必要はない
・Value Object・Application Service・Domain Events から入るのが費用対効果が高い
・Aggregate は重要だが最もコストが高く、慎重に導入する
・Domain Service は最後の手段として扱う
次章から、Value Object を起点に各パターンを深掘りしていく。まずは「最も費用対効果が高い」Value Object から始めよう。