AI がコードを書く時代に DDD は必要か?——単体サービスからシステム全体まで

先に結論:AI時代のDDDは「細工」より「地図」が効くんですよね

AIコーディングが日常になると、**戦術的DDD(Entity/VO/Repositoryなど)**は「型の良い実装テンプレ」としての価値が相対的に下がりやすいです。理由は単純で、**AIが得意なのが“局所の整ったコード生成”**だからなんですよね。

一方で、**戦略的DDD(Bounded Context / Context Map)**はむしろ価値が上がります。ここはAIが苦手な領域で、システム全体の境界・言語・責務・変更耐性といった「地図づくり」が中心になります。

たとえるなら、

  • 戦術的DDD:キッチンでの包丁さばき(AIがうまくなってきた)
  • 戦略的DDD:レストランのメニュー設計と厨房動線(AIだけだと事故りやすい)

という感じです。

この記事では、どこに設計コストをかけると効くかを、DDDの要素ごとに中立に整理します。


背景:AIが上手いのは「局所最適」、苦手なのは「境界の政治」なんですよ

AIコーディングツールは、次の条件が揃うほど強いです。

  • 入出力がはっきりしている
  • 既存コード・規約がある
  • 変更の影響範囲が限定される

逆に苦手なのは、こういう領域です。

  • 境界の設計(どこまでが誰の責任か)
  • 複数チーム・複数サービス間の整合性
  • 言葉の定義(「注文」「予約」「決済」みたいな曖昧語の取り扱い)
  • 例外系と運用(リトライ、補償、SLO、データ修復)

DDDでいうと、前者が戦術、後者が戦略に寄りやすい。なので「戦術DDDの価値低下・戦略DDDの価値向上」という構図が起きます。


戦術的DDD × AIコーディング:価値は下がるが、消えるわけでもない

ここでは戦術的DDDの要素を、AIとの相性で仕分けしてみます。

戦術DDDの主要要素と、AI時代の立ち位置

要素AIとの相性現場への影響筆者の評価
Entity / Value Object良い生成が速い。命名と不変条件は人が詰める必要「書く」より「ルール化」が価値
Repository / DAO良い典型コードはAIが量産。境界が曖昧だとデータアクセスが漏れる生成は簡単、設計は難しい
Domain Service普通何でも詰め込むと貧血化しやすい“何をここに置かないか”が重要
Aggregate / Invariant難しい寄り競合・整合性・トランザクション境界の判断が要るAIに任せると過分割・過集約が起きがち
Domain Event普通形は作れる。意味と契約が肝「イベント名の定義」が勝負

実務への影響

  • コード生成でEntity/VO/Repositoryが整っても、モデルの境界がズレると保守性が落ちるんですよね。
  • AIが作る“それっぽい”Repositoryは、気づくとユースケース都合のクエリ置き場になりやすいです(台所の引き出しが「なんでも入れ」になるやつです)。

評価(意見)

  • 戦術DDDは「職人芸のコーディング」を減らしてくれます。これは良い方向です。
  • ただし価値の中心は、クラスを増やすことではなく、不変条件と責務を言語化して、実装に落とすことに移ります。

今後の展望

AIはパターン実装をさらに得意にしていきます。なので戦術DDDは「型として学ぶ」より、設計上の制約をAIに渡せる形(ルール・テスト・仕様)にする方向へ寄っていくと思います。


「戦術DDDが効く場面」もあります:AIの出力を縛る柵として

戦術DDDがまだ効く典型は、次のような状況です。

  • チームが大きく、実装の癖がバラつく
  • ドメイン制約が多く、バグが事故につながる
  • 変更頻度が高く、仕様の誤解が起きやすい

ここでの戦術DDDは、**AIの生成物を“安全にする柵”**として機能します。

最小のコード例:VOで制約を閉じ込める(AIに書かせやすい形)

class Money {
  amount: int
  currency: string

  constructor(amount, currency) {
    require(amount >= 0)
    require(currency in ["JPY","USD"])
  }

  add(other: Money): Money {
    require(this.currency == other.currency)
    return Money(this.amount + other.amount, this.currency)
  }
}

ポイントは、実装の巧さではなく「requireに相当する不変条件が何か」を合意することです。AIはコード化が速いので、人は制約の定義に時間を寄せた方がリターンが出やすいですよね。


戦略的DDD × マイクロサービス:AIの限界が露わになる領域

マイクロサービスは、ざっくり言うと「分けた瞬間に分散システム」になります。 分散システムは、境界と契約が壊れると全体が壊れるんですよね。

戦略DDDは、その境界を決める技術です。

  • Bounded Context:言語・モデル・責務が一貫する範囲
  • Context Map:境界同士がどう接続するか(翻訳するのか、従属するのか、公開するのか)

ここはAIがコードを生成しても、境界そのものが間違っていると局所最適の積み上げが地獄になります。

なぜAIが戦略領域で苦戦するか

  1. 情報がコードにない
    • 「誰がオーナーか」「変更の痛みがどこに出るか」はリポジトリから読み取りにくいです。
  2. 評価関数が曖昧
    • 速度、独立性、整合性、監査、運用…最適化目標が複数あります。
  3. 組織と結びつく
    • 境界はチーム境界と絡みます。ここはアルゴリズムより政治(調整)です。

たとえるなら、AIは「レンガを積む」のは得意でも、「どこに橋を架けるか」は現地の地盤と交通量を見ないと決められない、みたいな話です。


Bounded Context:サービス分割の“正解探し”より「変更の衝突」を減らす

Bounded Contextを置く価値は、モデルを美しくすることというより、変更が衝突する範囲を閉じ込めることにあります。

実務で効く判断軸(AI時代でもここは人が握りたい)

  • 同じ用語が別の意味で使われているか
    例:「注文」が“購入意思”なのか“出荷指示”なのか
  • データ整合性が同期トランザクションを要求するか
    要求するなら同一境界に寄せる判断が出やすい
  • 変更の頻度が同じか
    一緒に変わるものは一緒に置いた方が楽
  • 障害時の影響を切りたいか
    “落ちてもいい境界”を作るのは戦略の仕事です

評価(意見)

戦略DDDは、AI時代ほど「投資対効果が読みやすい」設計です。なぜなら、境界が合っていると チームの手戻り・事故・調整が目に見えて減るからです。


Context Map:AIが書くコードの“接続先”を設計する

Context Mapは「サービス間の関係性の設計」です。ここが弱いと、AIが各サービスで綺麗なコードを書いても、接続部で事故ります。

代表的な関係(全部説明はしませんが、判断に使う観点だけ):

  • Published Language(公開言語):外部に出す契約を固定する。API/イベントの安定が優先。
  • Anti-Corruption Layer(ACL):相手のモデル汚染を防ぐ翻訳層。合併症を防ぐ隔離壁。
  • Conformist(追従):相手に合わせる。速いが主導権は相手。

図:コンテキスト間で「翻訳」を挟むと、変更が局所化します

flowchart LR A[Billing Context] -->|Published Language| API[Billing API / Events] API --> ACL[ACL: Translator] ACL --> B[Order Context]

実務への影響

  • 「直接DB参照」や「イベント名だけ合わせた実質RPC」は、短期では速いですが、境界の腐食が早いです。
  • AIが生成する統合コードは“動くもの”を作りがちなので、契約の所有者・互換性・バージョニングを先に決めないと事故が増えます。

比較:戦略DDD vs 代替アプローチ

  • API First / Schema First
    契約を固める点では近いです。違いは、戦略DDDは「言語・責務・翻訳関係」まで踏み込みます。
  • Team Topologies
    境界をチームから考えるのが強み。戦略DDDはドメインから境界を切る。両方を往復すると実務で効きます。

ユビキタス言語:AIプロンプト精度を上げる“語彙の圧縮”なんですよね

ユビキタス言語は「同じ単語を同じ意味で使う」取り組みですが、AI時代だと効能が増えます。

AIへの指示は、結局「言葉」です。 言葉が揺れると、AIの出力も揺れます。

例:同じ「注文」でも意味が違うと、AIは混線します

  • 注文(Order):カート確定〜決済前の意図
  • 受注(Sales Order):決済確定後の販売記録
  • 出荷指示(Fulfillment Order):倉庫へ渡す作業指示

この3つを全部「Order」で呼ぶ組織だと、AIに「Orderのステータスを追加して」と頼んだ瞬間、どのOrderの話かがブレます。

実務での効き方(プロンプト観点)

  • 用語集(Glossary)があると、プロンプトが短くても精度が出ます
    → 指示文が「圧縮」される感じです
  • コンテキストごとに同名語を分離すると、生成物が混ざりにくい
    → Bounded Contextがそのままプロンプトのスコープになります

筆者の評価(意見)

ユビキタス言語は、DDD経験が薄いチームでも投資価値があります。
理由は、人間同士の認識合わせと同時に、AIへの指示品質も上がるからです。


「戦術の価値低下 / 戦略の価値向上」をもう一段だけ分解する

ここ、誤解が起きやすいので整理します。

戦術DDDの価値が下がりやすいポイント

  • 典型実装はAIが高速に出せる
  • フォルダ構成・命名規約もテンプレ化できる
  • リファクタリング支援も強い

つまり「うまく書く」より「何を書くか」の比重が上がります。

戦略DDDの価値が上がるポイント

  • サービス境界、契約、データ所有、整合性…はコード生成だけで解けない
  • 組織・運用・将来の変更が絡む
  • 一度ズレると修正コストが大きい(データ移行、契約変更、チーム再編)

つまり戦略は「後から直しにくい」ので、先に丁寧にやる価値が上がります。


じゃあ現場でどこにコストをかける?判断のチェックリスト

1) まず戦略に寄せて投資したい項目

  • Bounded Contextの仮説と、用語の辞書(1枚でいい)
  • コンテキスト間の関係(Context Map)と、主要な統合パターン
  • データ所有の原則(どのサービスが真実の源泉か)
  • 整合性方針(同期が要る/結果整合でいく、補償の責務)

2) 戦術は「薄く、しかし芯は固く」

  • Entity/VOは「不変条件」を中心に
  • Repositoryは「境界外の都合」を混ぜない(クエリ置き場化に注意)
  • Aggregateは「競合と整合性」で決める(綺麗さで決めない)

3) AI活用前提でのおすすめ運用(ツール比較ではなく姿勢の話)

  • ユビキタス言語をプロンプトに埋め込む(用語定義へのリンクでも可)
  • 生成コードのレビュー観点を「境界」「契約」「不変条件」に寄せる
  • “どのコンテキストの話か”を指示の先頭に置く

まとめ:AIが書くのは「コード」、DDDが守るのは「意味」と「境界」

  • 戦術DDDは、AIによって実装コストが下がりやすい一方、不変条件の言語化という芯は残ります。
  • 戦略DDDは、マイクロサービスの境界・契約・整合性を扱い、AI単体では判断しにくいので価値が上がります。
  • ユビキタス言語は、人間の認識合わせに加えて、AIプロンプトの精度を上げるという新しい効能が出てきます。

DDDを「クラス設計の作法」として見ると、AI時代に色あせたように感じるかもですが、DDDの本丸は「モデルの意味を守る」ことなんですよね。
そして分散システムでは、意味がズレると静かに壊れていきます。静かに壊れるのが一番こわい、というやつです。

次に設計コストをかけるなら、クラス図を増やすより、境界と用語の地図を描くところから始めましょう。