TL;DR
- DDD (Domain-Driven Design) は複雑な業務を扱うための設計アプローチ
- DDDは 戦略DDD(Strategic DDD) と 戦術DDD (Tactical DDD) の2つに大別できる (本記事では前者にフォーカス)
- 戦略DDD では、境界 (Bounded Context) と言語 (Ubiquitous Language) を定め、複数の境界間の関係 (Context Map) を設計し、どこへ投資集中するか (Distillation) を決める
- MuleSoftの強みである API-led Connectivity という設計手法を活かすために 戦略DDD の考え方が重要
- そのためMuleSoftを題材として戦略DDDの具体的な適用例を確認する
想定読者
- モノリスの改善や疎結合化 (マイクロサービス化) に取り組んでいる
- DDDという用語は聞いたことがあり関心はあるが、一体何者なのかよく分からない
- DDDを学ぶために本を読んでみたが、その分量や抽象度の高さから挫折した経験がある
- MuleSoftは未経験でも問題なし
目次
- TL;DR
- 想定読者
- 目次
- 0. はじめに
- 1. 戦略DDDとは何か
- 2. 戦略DDDの3要素
- 3. MuleSoft概要
- 4. Bounded Context (BC) : 境界を切る
- 5. Ubiquitous Language (UL) : 言葉を揃えて書き起こす
- 6. Context Map (CM) : 境界間のつなぎ方
- 7. ACL: 翻訳を責務として置く
- 8. Distillation
- 9. 境界・関係・翻訳の位置関係
- まとめ
0. はじめに
本記事では、戦略DDDの概念・用語の解説から具体例まで解説します。
前半パートで戦略DDDとは何か?といった概念的な解説をした後に、後半パートで前半に学んだ概念をMuleSoftを題材に実際に適用していく、といった構成になっています。
なお、DDDに関する資料は沢山ありますが、本記事では以下を主要な参考文献としています。
-
Domain-Driven Design: Tackling Complexity in the Heart of Software
- DDDのバイブル。かなり分厚い。通称青本。
-
Domain-Driven Design Quickly
- 青本を要約して読みやすくしたもの。入門としてオススメ。
-
Implementing Domain-Driven Design
- DDDの概念を実装に落とすための実践書。通称IDDD。
-
DDD Distilled
- IDDDと同じ著者によって書かれたDDDの要点抽出版。こちらも入門としてオススメ。
1. 戦略DDDとは何か
まずそもそも、DDDとは何か?というところから始めましょう。
DDDは Domain-Driven Design(ドメイン駆動設計) の略で、複雑な業務(ドメイン)をチーム全体で正しく理解し、変更に強く複雑さに対処できる形で設計するためのアプローチです。つまり、「難しい業務のしくみを、みんなが同じ言葉で話せるように整理して、その理解をもとにソフトウェアを作ろう」 という方法論です。
DDDでの主役は技術ではなく、業務の理解とチームの共通認識です。まず業務を、チームで同じ言葉で理解し、その理解に沿ってコードやAPIを組み立てていきます。
DDDは大きく、次の2つの側面に分けて捉えられます。
- 戦略DDD (Strategic DDD): 大規模なモデルや複数チームの現実に合わせて、境界づけられたコンテキストを定義し、その相互関係を明示してドメインを分割・整合させる設計。
- 戦術DDD (Tactical DDD): 1つの境界づけられたコンテキストの中で、エンティティや集約などの戦術パターンを使ってドメインモデルをより精密に定義しコードへ落とす設計。
分かり易さ重視でざっくり言い換えると、以下のようなイメージです。
- 戦略DDD: 大きいシステムを作るときに、仕事の領域を「ここからここまで」と区切って、各領域がどうつながるかを決める考え方。
- 戦術DDD: 区切った領域の中で、データやルールをどう形にしてコードにするかを決める具体的な設計のやり方。
2. 戦略DDDの3要素
ここからは、戦略DDDの中でも特に重要な3つの要素を整理します。
戦略DDDは大きく、
- 境界 (Bounded Context) と 言語 (Ubiquitous Language) を定め
- 複数の 境界間の関係 (Context Map) を設計し
- どこへ投資集中するか (Distillation) を決める
といった流れで考えると整理しやすいです。
それでは、各要素について順に見ていきましょう。
2.1. Bounded Context / Ubiquitous Language
Bounded Context (BC) は「用語とモデルが一貫する範囲」を指します。
境界が変われば、同じ単語でも意味が変わることがあります。
- 例: 同じ「Status」でも、領域が違えば意味が違う
- 例: 同じ「Customer」でも、営業・請求・サポートで必要な情報や扱いが異なる
Ubiquitous Language (UL) は、BCの中で、「チーム全員が同じ意味で使う言葉」です。
業務側 (ドメインエキスパート) とエンジニアが同じ言葉で会話できるようにするための仕組みでもあります。
ULを整えることで、以下のような問題を防ぎやすくなります。
- APIがDB項目名や外部システム都合の命名に引っ張られる
- 仕様書と実装で言葉がズレて、レビューや運用が難しくなる
2.2. Context Map
BCを複数持つ場合に必要となってくるのがこの Context Map (CM) という概念です。
CMはBC同士が どのように依存し、どう連携するか を表します。
DDD Quicklyでは「複数のモデル(=複数のBC) と、それらの関係をアウトラインする文書」と説明されています。
CMで整理したい典型的な観点は次のとおりです。
- 上流/下流、主導権、契約 (Customer/Supplierなど)
- 依存の方向と変化の伝播 (どこが変わるとどこが壊れるか)
- 翻訳の要否 (ACLなど)
境界を決めても、境界間が密結合になってしまうと効果は薄れます。
CMは、そうならないために、境界間の適切な関係性を定義します。
DDD Quicklyに上げられている代表的なBC同士の関係パターンは以下です。
- Shared Kernel: 両チームが「ここだけは同じものを使おう」と一部を共同で維持する関係
- Customer-Supplier: 下流(Customer)側の要望が、上流(Supplier)側の優先順位や計画に反映される関係
- Anticorruption Layer: 上流側のモデルが自分たち(下流側)に侵入しないように、翻訳・変換の層を挟んだ上で繋がる関係
- Conformist: 下流側が変換を諦めて、上流側のモデルに合わせる関係
- Separate Ways: メリットが少ない場合に、あえて「統合しない」という関係
- Open Host Service: 上流側が「共通で使える公開API」を用意して提供する関係
今回はこのうち、今回の題材であるMuleSoftで重要になりやすいAnticorruption Layerをピックアップして簡単に説明します。
2.2.1. Anticorruption Layer
Anticorruption Layer (ACL) はAnticorruptionという名前の通り、別の境界から汚染されて腐敗するのを防ぐための層です。
境界Aのモデルや用語が、境界Bを汚染しないように、境界B側に防御の層を置きます。
実際の業務でよくある困りごととして、以下のようなものがあります。
- 外部システムの都合 (項目名・制約) が内側のAPIやドメインに漏れてくる
- いわゆる"共通モデル"に寄せた結果、意味の差分が潰れて破綻する
ACLはこれらを避けるために、主に次の役割を担います。
- 意味の翻訳
- データ整形
- オーケストレーション
2.3. Distillation
Distillation は、巨大なドメインを「全部きれいにモデル化する」のではなく、競争優位の源泉を特定し、設計・人材・品質投資を集中するための投資戦略です。
実務では次の3分類で考えると整理しやすいです。(流派による呼び名の揺れあり。)
- Core Domain: 競争優位の源泉。最高の設計・品質・人材を投入する。
- Supporting Subdomain: Core Domainを支えるが差別化ではない。十分に良く作る。
- Generic Subdomain: 他社も同じ。買う/使う/寄せる/外注の候補。
なお、ここで言うSubdomainは前述のBCとは異なることに注意します。
- Subdomain: 業務を「領域」に分けたもの (問題の地図)
- Bounded Context: モデルと言語を一貫させる「解決の境界」 (実装・チームの境界)
Core Domainを特定する中で、その副産物としてCore Domainを支えるSupporting Subdomainと、差別化にならないGeneric Subdomainが見えてきます。
ここまでで、戦略DDDの全体像と各構成要素の概要を紹介してきました。
ですが、DDD自体がそもそも抽象的な事もあり、ここまで読まれた皆さんの中には「あーそーゆーことね、完全に理解した (←わかってない)」という方も沢山いるかと思います。
まあ、原典で300ページ以上にも渡るボリュームがあるので、「この余白はそれを書くには狭すぎる。」という訳です。(言い訳)
というわけでここからは、「戦略DDDチョットワカル」を目指して、具体例を使って実践的に学んでいきます。
3. MuleSoft概要
まずは、今回題材として使う MuleSoft と、そこでよく出てくる API-led Connectivity の考え方を簡単に整理します。
その上で次章から、戦略DDDの要素 (BC/UL/CM/ACL/Distillation) が、設計の意思決定にどう効果的に働くのかを具体例に落としていきます。
MuleSoft はAPIの開発から運用までのAPI管理 (APIM) に必要な機能がAll-in-Oneで備わったクラウドプラットフォームで、Gartner社によるAPIM製品の調査 でもリーダーとして評価されるなど、APIMプラットフォームの代表的な存在です。
3.1 API-led Connectivity
MuleSoftではアプリケーション開発のアプローチとしてAPI-led Connectivityと呼ばれる考え方を採用しています。
API-led Connectivityは、ざっくり言うと
- 既存システムのデータを“使える形”で解放し
- それらを業務プロセスとして組み立て
- 利用者 (フロントエンド) ごとに“ちょうどいい形”で提供する
…というやり方を、「APIを3つの層に分ける」ことで実現する設計スタイルです。
MuleSoftの説明では、この3層は以下の役割になります。
- System API: 基幹やSaaSなど、各システムのデータを取り出せるようにする (“データの解放”)
- Process API: 複数のSystem APIを束ねて、業務プロセスとして意味のある形にする (“組み立て”)
- Experience API: UIや外部公開など、利用者に合わせた形で提供する (“届け方の最適化”)
以下がSalesforce公式ブログに掲載されているAPI-led Connectivityの概要図です。
このように各層で役割を分割し、再利用しながらマイクロサービス的に連携することで柔軟性と俊敏性を実現します。

引用元: What Is API-led Connectivity?
API-led Connectivityを採用すると、次のメリットが出ます。
- 再利用しやすい: System API / Process API を積み上げていくと、後続の開発が速くなる
- 変更に強い: 影響範囲が「どの層の変更か」で整理しやすい (例: チャネル変更ならExperience側で吸収しやすい)
3.2. MuleSoftで戦略DDDを扱う理由
上記で「MuleSoftはAPIを層で分けようね」という話をしましたが、現場ではよく以下のようになりがちです。
- とりあえずProcess APIに寄せ集める
- いつの間にかProcess APIが共通モデルの置き場になる
- 境界が曖昧なので、変更が入るたびに影響範囲が読めなくなる
この事故を避けるために効くのが、戦略DDDです。
ここまでで見た戦略DDDの各要素を、MuleSoftにあてはめるとこうなります。
- BC (境界) を決める → 「どこまでがどのAPIの責務か」が言えるようになる
- UL (言葉) を揃える → "共通モデル地獄"に引っ張られにくくなる
- CM (関係) を作る → 境界間の依存方向や連携方式を設計できる
- ACL (翻訳層) を置く → 別境界 (接続先API・外部システム) の都合でモデルが汚染されにくくなる
-
Distilling する → Core/Supporting/Genericを整理して、どこに設計・品質・運用の投資を集中するか決められる
- 例: Core Domainは再利用性・変更容易性を高めるための開発やガバナンスに投資する
- 例: Generic Subdomainは既製品・外部システムを前提に、System APIで"差異を吸収しつつ"繋ぐ
つまり、API-led Connectivityの「層」の考え方は便利ですが、層だけでは"意味の境界"は決まりません。
そのため、MuleSoftでは戦略DDDを使って、API-led Connectivityが破綻しないように全体の地図を先に作る ということが重要になってきます。
今回MuleSoftを利用しますが、他のツールで複数システム/サービスの連携を実現する場合も同様で、戦略DDDで「全体の地図」を作ることが重要です。
3.3. 次章以降でやること
次章からは、前章までに整理した戦略DDDの要素を、以下の順に具体例に当てはめていきます。
- まず Bounded Contex (境界) を切る
- 次に Ubiquitous Language (言葉) を揃える
- そのうえで Context Map (関係) を置く
- 必要な箇所に ACL (翻訳) を配置する
これで「戦略DDDチョットワカル」を目指していきましょう。
4. Bounded Context (BC) : 境界を切る
ここからが実践編です。
まずは「境界 (BC) を切る」ところから始めます。
このステップでは、まず "言葉のズレ"を手がかりに境界を仮置きする。そして、設計を進めながらインクリメンタルに育てていくのが現実的です。
重要なことは、いきなり完璧な境界を当てに行かないということです。はじめの一歩で時間をかけすぎると挫折の原因にもなりますし、何よりもまずは仮置きでもいいので境界を置くということが大切だからです。これにより、以降の設計を進める中でのズレに気づきやすくなります。
4.1. 例: 決済承認
今回は、どの業界でもあるあるな業務の決済承認を例にします。
今回は決済承認業務を、以下の3つの境界に分けて仮置きします。
- Request (申請): 申請の作成・修正・取消・提出、状態管理
- Approval (承認): 承認フロー、権限、差戻し
- Settlement (決済/精算): 請求・支払い・入金/精算、失敗や返金
境界が分かりやすくなる最大のヒントは、同じ単語でも意味が変わるポイントです。
| 単語 | Request (申請) での意味 | Approval (承認) での意味 | Settlement (決済/精算) での意味 |
|---|---|---|---|
| Status | Draft / Submitted / Cancelled | Approved / Rejected / Returned | Authorized / Captured / Failed / Refunded |
| “戻す” | 申請を取消す | 差戻して再提出させる | 返金する (Refund) |
| 締め/期限 | 提出期限 | 承認期限 | 請求締め・入金期限 |
この「同じ日本語なのに意味が違う」ものが出てきたら境界があるサインです。
4.2. 境界を決めるときの観点
境界設計の観点を以下に挙げます。
- 言葉の意味がズレるか (Status/Account/Order のような曖昧な言葉に注意)
- 意思決定者が違うか (申請者/承認者/経理 など)
- 変更理由が違うか (制度変更/承認ルール変更/決済手段変更 など)
- 失敗時の扱いが違うか (差戻し/取消/返金/再処理 など)
また、境界を決める際に良くある落とし穴が、「機能」で切ってしまうことです。これをすると高確率で境界が無くなります。
例: ApplicationService APIのように申請の一連の流れをひとまとめにしてしまう。
機能より先に、意味 (言葉) を見ることを意識しましょう。
4.3. MuleSoftでのBC
MuleSoftでは、BCを API資産(Mule App)の切り方 (= Exchangeに載せる単位) として扱うことが多いです。
そのため、MuleSoftではBCで意味の境界を決めた後は、以下の2点を意識して設計に落としていくと良いです。
-
BCごとにAPIを分ける
- Request API/Approval API/Settlement API のように「境界の言葉だけを話すAPI」にする
-
“全部入りAPI”を作らないよう気を付ける
- 例: 申請+承認+決済をまとめて返す
GET /applications/{id}のようなAPIを作らない
- 例: 申請+承認+決済をまとめて返す
5. Ubiquitous Language (UL) : 言葉を揃えて書き起こす
境界が仮置きできたら、次は UL (共通言語) を書き起こす フェーズです。
ここが曖昧だと、会議ではRequestと言っているのにAPIは /application になったりとチーム内での認識齟齬の原因になります。
5.1. ULを整理する際のコツ
ULを整理する際にはまずは以下の3点を意識すると良いです。
- 定義は1行で簡潔に記載する
- 複数の意味を持ちうる曖昧な単語は明確化する
- 具体例で伝える
今回の決済承認のRequest境界を例に、いくつかULを定義してみると以下のような感じです。
| 用語 | 種別 | 1行定義 (Request境界での意味) | 例・補足 |
|---|---|---|---|
| Request | 名詞 | 申請者が作成し提出する、承認対象の申請データ | 例: 経費申請、支払申請 |
| requester | 名詞 | 申請を作成・提出するユーザー | requesterId |
| requestId | 名詞 | Requestを一意に識別するID | r-001 |
| RequestStatus | 名詞 | Requestの状態 | DRAFT/SUBMITTED/CANCELLED |
| DRAFT | 状態 | まだ提出されていない下書き状態 | 編集可能 |
| SUBMITTED | 状態 | 提出済みで、承認プロセスの対象になった状態 | RequestSubmitted |
| CANCELLED | 状態 | 申請者都合で取り下げた状態 | 承認とは別物 |
| Submit | 動詞 | RequestをSUBMITTEDへ遷移させる操作 | POST /requests/{id}:submit |
| Cancel | 動詞 | RequestをCANCELLEDへ遷移させる操作 | POST /requests/{id}:cancel |
| RequestSubmitted | イベント | Requestが提出されたという事実 | 下流 (Approval) が購読 |
| RequestCancelled | イベント | Requestが取り下げられたという事実 | 承認中止の起点になり得る |
ULは「使うの面倒くさいなあ」となって誰も使わなくなってしまったらお終いです。
上記のコツを意識して、簡潔・明確・具体的をキーワードに定義しましょう。
5.2. MuleSoftでのUL記述
MuleSoftでは、Design-firstという、API仕様を信頼できるソース・契機としてそこから開発を進める考え方を推奨しています。
加えて、MuleSoftは仕様をAnypoint Exchangeというポータルで共有することができます。
ULは専用のドキュメントのみで管理すると、徐々に実装と乖離がでて陳腐化しがちです。
なので、MuleSoftでは API仕様をULの単一の拠り所 (Single Source of Truth) にして運用するのが良いです。
この運用にすると、ULが「ドキュメントとしては正しいけど実装は違う」になりにくく、MuleSoftの資産 (Exchange) として育つ状態を作れます。
5.3. API仕様にULを刻む
では、実際にAPI仕様にULを刻んでいきます。
最低限意識すべき事項として命名/スキーマ/エラー/例の4項目の書き方を見ながら、今回の決済承認のRequest境界を例にAPI仕様のサンプルを記述していきます。
5.3.1 命名
命名時には名詞と 動詞 を分けてリソースと操作を明確に区別します。
- リソースは 名詞 (Request / Approval / Settlement)
- 操作は 意図が読める形 (submit / approve / return)
操作は基本はHTTPメソッドで表現しつつ、HTTPメソッドの都合で表現しきれない「意図の強い操作」は、アクションとして切り出します。
例 (Request境界) :
-
POST /requests(申請を作る) -
PATCH /requests/{requestId}(申請を修正) -
POST /requests/{requestId}:submit(申請を提出する)
5.3.2 スキーマ
スキーマでは、項目名で意味を、Enumで境界の言葉を明確化します。
- 項目名で"意味"を表現する
- 申請用のIDは単にIdではなくrequestIdのようにする- 日付は
date-time(タイムゾーン含む) とdateのようにする
- 日付は
- 列挙 (Enum) を“境界の言葉”として定義する
- Request境界のstatus:
DRAFT / SUBMITTED / CANCELLED - Approval境界status:
APPROVED / REJECTED / RETURNED
- Request境界のstatus:
5.3.3 エラー
エラーは、仕様としての境界線です。
ここが曖昧だと、呼び出し側が勝手に解釈して結合が強くなります。
よく使うエラーコードの方針を簡単に整理すると以下のようになります。
- 400: 不正な入力 (必須不足、形式違い)
- 401/403: 認証認可の失敗
- 404: 存在しない
- 409: 状態遷移できない (整合性・競合)
- 422: 意味的に受け付けられない (業務ルール違反)
- 500: サーバ内部のエラー
ここで大事なのは、これらのエラーコードをきちんと使い分けることです。
5.3.4. 例
ULは文章で説明するより、例で伝える方が早いです。
- リクエスト例: 何が必須で、何が任意か
- レスポンス例: どんな状態遷移が起きるのか
- エラー例: 何が境界外 (禁止) なのか
OpenAPIには example / examples を入れられます。
まずは面倒くさがらずに、「代表例1つ」から始めてみましょう。
5.3.5. Request境界のサンプルAPI仕様
Request境界におけるULを、ここまで話した「命名・スキーマ・エラー・例」の観点に基づき整理して、API仕様の形に整理したものを以下に記載します。 (最小形かつ一部省略あり)
openapi: 3.0.3
info:
title: Request API
version: 1.0.0
paths:
/requests:
post:
summary: Create a request
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/CreateRequest' }
examples:
basic:
value:
requesterId: "u_123"
title: "Travel expense"
amount: 12000
currency: "JPY"
responses:
'201':
description: Created
content:
application/json:
schema: { $ref: '#/components/schemas/Request' }
/requests/{requestId}:submit:
post:
summary: Submit a request
parameters:
- name: requestId
in: path
required: true
schema: { type: string }
responses:
'202': { description: Accepted }
'409':
description: Conflict (invalid state transition)
content:
application/json:
schema: { $ref: '#/components/schemas/ErrorResponse' }
examples:
alreadySubmitted:
value:
code: "REQUEST_ALREADY_SUBMITTED"
message: "This request is already submitted."
components:
schemas:
CreateRequest:
type: object
required: [requesterId, title, amount, currency]
properties:
requesterId: { type: string }
title: { type: string }
amount: { type: integer }
currency: { type: string, example: "JPY" }
Request:
type: object
required: [requestId, status]
properties:
requestId: { type: string }
status:
type: string
enum: [DRAFT, SUBMITTED, CANCELLED]
6. Context Map (CM) : 境界間のつなぎ方
境界とULが仮置きできたら、次は「つなぎ方」です。
Context Mapを設計する際に決めたいのは主に以下の2つです。
- 依存方向 (上流/下流)
- 連携方式 (同期API/イベント)
6.1. 依存方向
まず依存方向から決めていきます。
依存方向というのは 「どっちが変化の主導か」 です。
- 上流 (Upstream): その境界のモデルが"基準"となり、変化の主導権を持つ。
- 下流 (Downstream): 上流の変化に追従する側。
依存方向が曖昧だと、仕様変更のたびに「どっちが合わせるの?」「こっちは合わせる工数ないよ」と言った面倒な調整事の原因となります。
今回の例は以下のような関係になっています。
- Request (申請) は業務の起点
- Approval (承認) は申請の事実を受けて状態を作る
- Settlement (決済/精算) は承認の事実を受けて処理する
ですので、以下の図のような依存関係が自然です。
上流 [Request] --(Submitted)--> [Approval] --(Approved)--> [Settlement] 下流
6.2. 連携方式
次に考えるのが連携方式です。
上記で描いた各境界間の連携が「同期API」と「イベント」どちらに向いているのかを考えます。
ここは色々な考え方がありますが、迷ったらまず以下の表をベースにどちらが向いていそうか考えてみてください。
| 観点 | 同期APIが合う | イベントが合う |
|---|---|---|
| UX | 即時に結果が必要 | 受付できればOK (後で反映) |
| 失敗時 | その場で返す | リトライ/DLQ/補償で回復 |
| 結合度 | 高くなりやすい | 低くしやすい |
| 運用 | 最初はシンプルだが呼出しの階層が深まると複雑に | 最初は難しいが拡張と回復が強い |
今回の例では以下の図のようにCMを設計してみました。
7. ACL: 翻訳を責務として置く
境界を切って、関係を置くと、次に必ず出てくるのが「別境界との翻訳はどうする?」という問題です。
今回はMuleSoftで頻出のACLを使います。
7.1 ACLの役割と置き場
ACLの主な責務は、前半でも触れたように以下の3つです。
-
意味の翻訳
- 例: 外部のモデル → 自境界の用語に変換
-
データ整形
- 例: 巨大なレスポンスから必要項目だけ抽出
-
オーケストレーション
- 例: 複数System APIを呼んで統合する
また、ACLは「境界間の接点」に置きます。
- 同期: A境界API ⇄ ACL ⇄ 外部/他境界API
- 非同期: イベント ⇄ ACL (変換) ⇄ 別境界のイベント/モデル
7.2 例: Request → Approval をACLで繋ぐ
今回の決済承認の例のRequest境界とApproval境界をACLで繋ぐ場合を見ていきます。
Request境界側が出すのは 「申請が提出された」 という事実です。
-
RequestSubmitted(申請が提出された) を送る
一方、Approval側が欲しいのは 「承認依頼」 です。
- Approval境界の言葉でいうと、「承認依頼 (Approval.requested) が来た」が欲しい
ここでACLがやること:
-
RequestSubmittedを受ける - Approval境界の言葉に変換して
approval.requestedを発行する
この変換がACLの「意味の翻訳」です。
7.3. MuleSoftでACLを作るときの定番の役割分担
MuleSoftのAPI-led Connectivityに寄せると、責務が整理しやすいです。
- System API: 外部都合の吸収 (認証、項目名、制約、レート、プロトコル差)
- Process API: ACL (意味の翻訳、データ整形、最小合成)
- Experience API: 画面/チャネル最適化
7.4. ACLの実装フロー
8. Distillation
ここまでで「境界」「言葉」「関係」「翻訳」を作ってきました。
最後にDistillationで、作り込みの濃淡 を決めます。
ここでやりたいことは業務を以下の3つに分類し、投資配分を決めることです。
- Core Domain: ここに全力。設計・品質・運用に投資する
- Supporting Subdomain: ここは良しなに。過不足なく作る
- Generic Subdomain: 差別化しない。買う/寄せる/任せる (繋ぐだけに寄せる)
8.1 MuleSoftにおけるDistillationの適用
MuleSoftにおいては、以下のように整理すると分かりやすいです。
| 区分 | 何を頑張る? | MuleSoftでの投資ポイント例 |
|---|---|---|
| Core Domain | 再利用性・変更容易性・高品質 | API仕様を丁寧に(命名/スキーマ/例/エラーを磨く)。ガバナンス・監視・SLOを強めに。 |
| Supporting | ちゃんと動く | ロジックは過剰に抱えない。テスト/監視は必要十分。 |
| Generic | こだわらない (差別化しない) | 外部SaaS/基幹システムを前提にSystem APIで連携して都合を吸収。変換はACLで最小に。 |
Distillationを行うことで、「どのAPIを"資産として育てる"か」、「どこは割り切って"繋ぐだけにする"か」 が言語化できます。
9. 境界・関係・翻訳の位置関係
最後に、ここまでの要素を1枚にまとめます。
まとめ
- DDDは複雑な業務を戦略 (全体の分割と関係) と 戦術 (詳細なモデル化と実装) の両面で進めて複雑さに対処できるシステムを設計するためのアプローチです。
- 本記事では戦略DDDを対象とし、 境界と言語 (BC/UL) を揃え、次に 境界間の関係 (Context Map) の定義、特にACL での汚染防御を行い、さらに Distillation で投資の濃淡を決めるといった戦略DDDの一連の考え方を解説しました。
- 後半パートでは、戦略DDDの要素を実際の設計に適用する方法をMuleSoftを題材にして整理しました。
- BC: 意味 (言葉のズレ) を手がかりに境界を仮置きする
- UL: API仕様に刻む (命名・スキーマ・例・エラー)
- CM: 依存方向と連携方式を決める (同期チェーンを避ける)
- ACL: 翻訳点を責務として閉じ込める (Process APIの肥大化を防ぐ)
- Distillation: どこに投資するかを決める (Core/Supporting/Generic)
- もしこの記事でDDDを少しでも良いと思った方は、ぜひ小さくでも良いので皆さんの現場にも適用してみてください。
- また、もっとDDDに興味が出てもっと知りたいと思った方は、冒頭に挙げたようなドキュメントを直接読んでみると良いと思います。
※ MuleSoftは、Salesforce.com, Inc.の商標または登録商標です。