第31章:ACL入門A(なぜ必要?)🛡️
この章でできるようになること🎯✨
- ACL(Anti-Corruption Layer / 腐敗防止層)が 何のために存在するのか を、言葉で説明できる😊
- 「別BC・外部システムとつながる時、どこが壊れやすいか」を 具体例で想像できる 🧠💡
- 「ACLを入れるべき状況/入れなくていい状況」の 見分けの感覚 がつく👀✅
ACLを一言でいうと🧱🌊

ACL=“相手のクセ”を、自分のドメインに持ち込まないための翻訳&防波堤 だよ🛡️✨ 別BCやレガシー、外部APIと話すときに、自分のモデルが汚れないように 間に“変換レイヤー”を置く考え方!(Microsoft Learn)
1) そもそも何が「腐敗(corruption)」なの?😵💫🧪
ここでいう腐敗は、「悪いことした」じゃなくて… 外の都合で、こっちのドメインがグチャグチャになること😭💥
たとえば👇
- 外部が
status = 1/2/3みたいな数字コードしか返さない → こっちのドメインにもint StatusCodeが増える😇 - 外部が
"Y"/"N"を使う → こっちがboolで表現できなくなって変換if地獄へ😵💫 - 外部の「顧客(Customer)」が、こっちの「顧客」と意味が違う → 同名なのに中身が別物で事故る🧨
こういうのが積み上がると、ドメインモデルが“外部仕様の寄せ集め”になってしまうんだよね…🥲
2) ACLが必要になる典型パターン🏥🧩
ACLが活躍するのは、だいたいこのへん👇
パターンA:別BCとつながる(特に“相手が強い”)🔗👑
Context Mapでいう「上流/下流」みたいな関係で、 下流(= 使う側)が“相手に合わせないといけない”状況ってあるよね🙇♀️ このとき、下流側が 自分のドメインを守るために翻訳を持つ のがACLの発想だよ🛡️(DevIQ)
パターンB:外部サービス・SaaS・ベンダーAPIとつながる🌐📨
外部APIは、突然フィールド名が変わったり、仕様が微妙にズレたりする😇 だから “外の変化”を内側へ直撃させない のが超重要!(Microsoft Learn)
パターンC:レガシーとつながる(移行中)🏚️➡️🏗️
レガシーは「命名」「単位」「null文化」「状態管理」が独特なことが多い😂 それを新しいドメインへ直入れすると、新システムまでレガシー化しちゃう…😱 そこでACLで “接続だけする” のが定番だよ🛡️(Microsoft Learn)
3) ミニECでイメージ:配送BC×外部配送API🚚📦
たとえば「配送BC(Shipping)」が、外部の配送会社APIを呼ぶケース!
外部APIが返してくるのがこんな感じだとするね👇
delivery_status: "IN_TRANSIT"eta_days: 2(営業日なのか暦日なのか不明😇)- 住所が
address1/address2で分かれてたり、逆に1本だったり…
ここで ACLなし で配送BCが外部レスポンスを直接扱うと…
- 配送BCの中に、外部の
delivery_statusがそのまま入り込む😵💫 - 「ETAが営業日/暦日どっち?」問題が、ドメインのあちこちに散らばる🧨
- 仕様変更で、配送BCのドメインやユースケースまで巻き込まれて修羅場🔥
5) 図で理解:ACLは“境界の玄関”🏠🚪
イメージはこれ👇
(自分のBCの世界) (相手の世界)
ドメインモデル ←→ ACL ←→ 外部API / 別BC / レガシー
きれい✨ 翻訳📖 クセ強め😇
ポイントは1つ! 「自分のBCの中は、自分の言葉・自分の型で統一する」✅ 相手のクセは ACLの中でだけ 面倒を見る🧹🛡️(Microsoft Learn)
6) ACLがないと起きがちな“3つの事故”💥💥💥

事故①:ドメインが“外部仕様カタログ”になる📚😇
本来、ドメインは業務ルールを表すはずなのに、 外部都合のフィールドやコード値が入ってきて「意味の一貫性」が崩れる😭
事故②:if文の森が生える🌳🌳🌳
if(status==2) ... とか
if(flag=="Y") ... とかが、いろんな場所に散らばる…😵💫
“変換”が分散すると、変更時に全部探す羽目になる🔍💦
事故③:テストがつらくなる🧪💔
外部レスポンス形式がドメインに混ざると、 テストが「外部形式前提」になって 読みづらい・壊れやすい 😭 ACLがあると、ドメインはドメインの言葉でテストできる よ🧡(Microsoft Learn)
6) ACLがあると何が嬉しい?🎁✨
- 外部仕様が変わっても、直す場所が ACLに集約 される🔧✅
- ドメインは「自分の用語」「自分の型」「自分のルール」で保てる🧠✨
- 連携の“汚いところ”を、境界に押し込められる🧹🛡️
- 「どこまでがドメイン?」が明確になって、チームで話しやすい💬🌸(microservices.io)
7) “翻訳”って、何を翻訳するの?📖🔁
ACLが翻訳するのは、主にこの4つだよ👇
- 名前(用語):
customerがこっちのMemberに相当する…など🏷️ - 型(表現):
"Y"/"N"→bool、"2026/02/02"→DateOnlyなど🧩 - 単位・ルール:円/ドル、税込/税抜、営業日/暦日…💴📏
- 欠損・例外文化:nullが来る、空文字が来る、0が来る…😇
これを ドメインの外(境界)で吸収する のがACL!(Microsoft Learn)
8) ちょい注意:ACLは“魔法”じゃない⚠️🧯
ACLを置くと良いこと多いけど、万能ではないよ👇
- レイヤーが1枚増える → 実装・監視・運用の手間も増える📦
- 変換が重いと 遅延 が出ることもある⏱️
- 何でもACLに押し込むと、ACLが肥大化して“第二のレガシー”になる😵💫
このへんは Microsoft の Azure Architecture Center でも注意点として挙げられてるよ🧯(Microsoft Learn)
9) “ACLを入れる?”判断チェック✅👀
次の質問に「うん…そうかも」が多いほど、ACLの出番だよ🛡️✨
- 相手の用語や型が、こっちの用語とズレてる?🧨
- 相手の仕様変更が、こっちの開発計画と独立して起きる?🔁
- 相手のデータが「欠損」「例外」「コード値」多め?😇
- 直接つなぐと、ドメインの中に変換ロジックが散らばりそう?🌳
- 「相手に合わせる」しか選べない関係?🙇♀️(下流側つらい)(DevIQ)
10) ミニ演習(頭の中でOK)🧠🎮
配送BCが外部配送APIを呼ぶとして、外部からこれが返ってくる👇
delivery_status = "DONE"eta_days = 0address = ""(空文字…?)
このとき考えてみてね😊
- 配送BCのドメインでは、状態は何型がいい?(string?enum?ValueObject?)🏷️
eta_days=0は「到着済み」なのか「未計算」なのか?🤔address=""は「住所なし」なのか「相手の仕様上の空」なのか?😵💫- それを どこで吸収 する?(ドメインの中?それともACL?)🛡️
11) お助けAIプロンプト🤖✨
- 「この外部APIレスポンスの“クセ”を列挙して。型・単位・欠損・命名の観点で!」🔍
- 「このレスポンスを、配送BCのユビキタス言語に合う形へ変換する案を出して!」📖
- 「ACLに閉じ込めるべき変換ルールを、箇条書きで仕様として書いて!」📌
- 「変換が散らばると危険なポイントを、保守の観点で説明して!」🧯
まとめ🧡
ACLは、別BC・外部・レガシーの“クセ”から 自分のドメインを守る防波堤 🛡️🌊 境界に“翻訳係”を置くことで、ドメインがきれいなまま育つ🌱✨(microservices.io)