コンテンツにスキップ

DDD ユビキタス言語は「用語集」では管理できない問題と対策

概要

ドメイン駆動設計(DDD)のユビキタス言語(Ubiquitous Language)を「用語集」として管理しようとすると限界がある。その理由と、現実的な代替手段を解説した note 記事のポスト。

ユビキタス言語とは

DDD における重要な概念。開発者とドメインエキスパート(ビジネス側)が 同じ言葉 を使ってシステムを語れるようにする取り組み。

NG: 開発者が「User テーブル」「Order レコード」と言い、
    ビジネス側が「お客様」「ご注文」と言う
    → 会話が噛み合わず認識ずれが生まれる

OK: 両者が「顧客(Customer)」「注文(Order)」という同じ言葉を使う
    → コードにもビジネスの言葉がそのまま現れる

なぜ「用語集」では管理できないのか

よくある失敗パターン:Notion や Confluence に「用語集」ページを作る

問題点:

1. 文脈(コンテキスト)が失われる

「注文」という言葉ひとつでも、文脈によって意味が変わる。

受注処理チーム: 注文 = 受注確定前の仮状態も含む
請求チーム:     注文 = 支払い完了済みのもの
在庫チーム:     注文 = 出荷指示が発行されたもの

用語集に「注文 = 顧客がリクエストした購買意図」とだけ書いても、上記の文脈の違いは表現できない。

2. 動作・振る舞いが書けない

ユビキタス言語は名詞だけでなく、動詞(ビジネスルール) も含む。

注文を「確定する」とはどういうことか?
  → 在庫を引き当てる
  → 請求を発行する
  → 顧客にメールを送る
  → キャンセル不可になる

これらの振る舞いは用語集の「定義欄」に書けない。

3. メンテナンスされない

用語集は書いた時点でのスナップショット。ドメインが進化しても更新されず、現実と乖離していく。

現実的な代替手段

1. 境界づけられたコンテキスト(Bounded Context)で管理する

同じ言葉が複数の意味を持つなら、コンテキストを分ける

受注コンテキスト: Order(受注中)
請求コンテキスト: Invoice(請求済み注文)
出荷コンテキスト: Shipment(出荷待ち注文)

それぞれのコンテキスト内では言葉が一意になる。

2. ユビキタス言語をコードに体現させる

言葉がコードに現れていることが最善の「文書」になる。

// NG: 汎用的な名前(ドメイン言語が消えている)
func (s *Service) Process(id int) error { ... }

// OK: ユビキタス言語がコードに現れる
func (o *OrderService) ConfirmOrder(orderID OrderID) error { ... }
func (o *OrderService) CancelOrder(orderID OrderID, reason CancellationReason) error { ... }

3. ドメインエキスパートとの継続的な対話

用語集を一度作って終わりではなく、定期的にドメインエキスパートとコードを一緒に読むセッションを設ける。

コードが「ビジネスの言葉」で読めるかどうかを確認する。

なぜ重要か / いつ使うか

  • チームで DDD を導入しようとしているとき
  • ビジネス側と開発側の認識ずれが頻繁に起きているとき
  • 「用語集」を作ったのに誰も参照しなくなったとき
  • 複数チームが同じ言葉を異なる意味で使っていることに気づいたとき