久しぶりの技術ブログの更新です。 担当していた中期のプロジェクトが終わり、時間ができたので、アウトプットも兼ねて技術記事を投稿しようと思います。
現職のデザインファームのコンサルタントとしての仕事も楽しいのですが、最近転職もうっすら視野に入れています。
転職先として海外出張や赴任の多い仕事を知ってらっしゃる方、もしくは現職の仕事として探索的なプロダクト開発を一緒にやりたいという方がいたらぜひご連絡ください笑
さて、本題です。
前回の更新からソフトウェアプロダクトの開発界隈はかなり様変わりしてしまいました。
おそらくですが、多くのエンジニアが何かしらの業務でClaude CodeやCodexなどの生成AIに助力を乞いながら製品開発を進めているのではないでしょうか??
僕自身、業務で自身でコードを書くのは生成AIが賄いきれない場所、何度もスタック・ループしてしまう箇所で参考にするためのコードを書く程度になってきています。
最近の技術的な議論の中心もほとんどが生成AI関連の話題に埋め尽くされ、設計の正しさやアーキテクチャの美しさに関する議論はかなり少なくなってきたように感じます。
また、設計理論をもとに実践的な開発活動を通じて得られた知見も、生成AIとの対話で解決してしまうせいか、あまり共有されなくなってきたなと感じています。少し寂しいですね。
さて、今回のブログでは、そういった実践的な開発活動の中で、ずっと僕が感じていたDDDを採用し続けた中での違和感について書いていきたいと思います。
なお、この記事でいう「DDDの採用」とは、ユビキタス言語やBounded Contextといった考え方を部分的に参照することではなく、ドメインモデルをソフトウェア設計の中心に据え、Tactical DDDを表現手段として用いながら継続的にモデルを育てていく開発スタイルを指します。
おそらく多くの開発現場でDDDを採用するというのはそういう文脈で使われているかと思いますが、設計思想だけをチームの共通コンテクストとして持ちながら、全面的にDDDを推しているわけではないというチームには当てはまりません。
また、久々の技術ブログなので、勘を取り戻す意味も込めて、基本的に自筆で書こうと考えています。
生成AIに言い回しや技術的な正しさのレビューはお願いする予定ですが、生成AIに教えてもらった自分にはない知見を自分の言葉のように語るのは避けたいので、自分からは出てこなかった考え方や知識は引用の形で追記しようと思います。
誤字脱字や表記ゆれが多々あるかと思いますが、どうぞお許しください...
目次
- 目次
- 1. DDD自体は非常に有用な設計理論であるということ
- 2. DDDは教育・学習コストが高すぎる
- 3. チーム内のコミュニケーションコストが跳ね上がる
- 4. 探索的開発ではBounded Contextが変わりやすい
- 5. 日本語でのユビキタス言語とプログラムの相性がとにかく悪い
- 6. ドメインエキスパートとの対話が実現しないことが多い
- 7. 地味に生成AIとも相性が悪い(と感じる)
- 8. どのようなチームやプロダクトでいつDDDを採用すべきなのか
- (余談)今後もしかしたらDDDを採用すべきプロダクトが20%くらいになるかもしれない点について
- 最後に
1. DDD自体は非常に有用な設計理論であるということ
この記事を始めるにあたり、まずDDD自体を否定する意図がないことを書いておきたいと思います。
僕がDDDに出会ったのはおよそ10年前で、当時の上司の方からこれ面白いから勉強してみてと渡された本がエヴァンスの「Domain-Driven Design」でした。(最初は日本語の「ドメイン駆動設計」を読んだのですが、翻訳がしっくりこなかったので、結局英語版の原書を購入しました。今でもよく読み返しています。)
当時はいち開発者にすぎず、すぐにプロダクトに導入する権限はなかったのですが、前職や現職でテックリードを任された際は積極的に採用してきました。
おそらく10年近くはDDDと向き合い続け、最近やっと自分の設計手法の手札として柔軟に取り扱えるようになってきたように思います。
個人的にドメイン駆動設計に関して最も魅力的に感じる点は、設計の基本思想がドメインエキスパートとの協調にあり、可読性や保守性、パフォーマンスなどの技術的な正しさに閉じていない点にあります。
コード自体にドメインエキスパートの知識を集約させ、状態変化や業務ルールをドメインモデルとして表現し、単一のモデルでは表現できないルールをDomain Serviceとして扱いつつ、アプリケーションレイヤーによってユースケース全体を協調させるという設計思想は、顧客との協調を主眼とするアジャイルとも非常に相性が良いように感じました。
新しい機能開発をする際にも、業務上の知見共有や採集をしながらどのようにコードで表現するかを考えるのが習慣化されるため、コードに落とす行為自体もかなり自然かつスムーズにできるようになり、生成AI以前はかなり強力なアシストだなと感じておりました。
現職はユーザー中心のプロダクト開発を強く重視するフィンランドの中でもさらにアジャイルに特化した組織のため、ユーザーとのコミュニケーション量は群を抜いて高く、エンジニアもユーザーインタビューや現場に足を運ぶこともざらにありました。
エンジニアがビジネスに対する高い理解を求められる一方、その中で得られた膨大なユーザー知見をドキュメントのみで管理するのはかなり苦しく、ビジネス知見がコード上に顧客と同じ文脈で表現されているというのは、ビジネスコンテクストを瞬時に理解することにも非常に貢献してくれたと思います。
では、そんなDDDがなぜ99%のチームには向かないと考えるに至ったか、次の章から視点ごとに分けて書いていきたいと思います。
2. DDDは教育・学習コストが高すぎる
まず日本でよくDDDについて挙げられる感想として、DDDは学習コストが高すぎるという点があります。
DDDの最も重要な考え方はドメインエキスパートとの対話を通して共有モデルと共有言語を作り、それを実装にも反映しながら継続的に更新していくことにあります。
また、その代表的な表現方法の一つとしてTactical DDDと呼ばれるEntityやVO, Repositoryなども存在しますが、それぞれがなぜビジネスを表現することに繋がるかを意識しながら学ぶ必要があります。
しかし、この考え方はGoFのデザインパターンのようにコード例から形を理解しやすいものや、マイクロサービスアーキテクチャのように構成図として表現しやすいものとは異なり、DDDは背景にあるモデルの意図を理解しなければ、コードだけを見ても価値を把握しにくい設計アプローチです。
「ドメイン駆動設計」という原典自体が非常に抽象度が高くまたそれなりに長い文章でありながら、それを読むだけでは成り立たず、ドメインエキスパートやユーザーとの対話を通じて四苦八苦しながらモデルをこね回し、表現方法を探求する中でやっと勘所が掴めてくると言った類のものであるため、学習コストは非常に高いです。
つまり、僕が個人的に魅力であると感じる「技術的な正しさに閉じていない」点は、むしろチーム展開するにあたっては、各人に基本的な概念を学習してもらった上で、DDDという設計について実践的な学びを積み重ねなければいけないというデメリットでもあるのです。
ソフトウェアの設計原則を考える際、保守性や可読性、パフォーマンスやセキュリティなどの技術的な要件ももちろん大事なのですが、プロダクトはチーム開発されるものであり、また人員も移り変わっていくことを考えると、学習コストも無視はできません。
DDDは移り変わるビジネス要件にモデルを更新・分割・統合しながら柔軟に対応できることも求められます。
DDDのメリットを長期的に維持するには、チーム全体が共通言語としてDDDを使えることに加え、Strategic DDDやドメインモデリングを理解し、モデルや境界の変化を継続的にレビューできるメンバーが複数必要になりますが、こう言ったチームはあまり現実的ではありません。(少なくとも僕は見たことがありません。)
また、DDDを勉強している方の中でも、DDDの抽象的概念の理解や実践を諦めて、Tactical DDDの表層にのみ理解を絞った結果、ビジネスルールが一切乗らない貧血症のモデルだらけになることも珍しくありません。
そう言った教育・学習コストを無視できるほどゆとりのあるチームや、DDDを標準知識として兼ね備えてるメンバーだらけのチームというのは、おそらく日本中探してもほとんど存在しないのではないかと考えています。
3. チーム内のコミュニケーションコストが跳ね上がる
DDDのもう一つのデメリットとして、DDDに関する議論がかなり増え、コミュニケーションコストが跳ね上がる点にあります。
アジャイルやスクラムにしろDDDにしろ、ユーザーや開発者同士のコミュニケーションを前提としており、DDDの導入によりコミュニケーションコストが上がること自体はプロダクトの改善に必要なものだと考えています。
一方で、DDDを導入することで同時に、DDDそのものをどうすべきかに関する議論が非常に増えます。
例えば、context boundaryはどこか、aggregate rootは何にすべきか、これはEntityにすべきかVOにすべきか、このビジネスロジックの表現はどこに持たせるべきか、パフォーマンスとの兼ね合いはどうするか、ドメインモデルを分割すべきか、DDD的には何が正しいのかと言ったトピックが、毎日いとまもなく吹き上がり続けます。
業務をモデルでどう表現するか、ビジネスルールは正しく表現されているか、コンテクストの切り方を見直すべきかなど、モデルそのものの価値を向上させるための議論は非常に有益ですが、実際の開発現場でのレビューはどちらかというとコード上の設計や実装に関する議論ばかりになることも多く、またその認識の違いやズレを解消することにもかなりの時間がかかります。
また、前述の教育コストの話にも関わりますが、DDDをあまり知らない・経験したことがない開発者に向けて、「DDDではこう考えるからここはこう表現すべき」といった指摘事項もかなり増えます。
アジャイルやDDDにおける顧客やチーム内の議論はプロダクト価値の向上に大きく関わる重要なコストではありますが、DDDとして何が正しいかの議論は議論としては面白い一方、この議論自体がプロダクトの価値や生産性に結びついているのかと感じることも多いです。
DDD熱が高かった時期はそう言った議論こそエンジニアリングの面白さだと考えていましたが、現職に就いてプロダクト価値やユーザー価値に関心の中心が移ってからは、DDDを採用しなければこんな議論に時間を割かなくても良かったのではと考えることもそれなりにありました。
また、部署異動や保守ベンダーへの引き継ぎでチームそのものが総入れ替えになった場合、それらの議論で出来上がった美しいドメインモデルが正しく維持・拡張される保証はありません。
DDDの価値はコードだけでなく、チームが共有する言語とモデルにも依存しているため、チーム交代時にその文脈を引き継げないと価値が失われやすく、また先述の学習コストの高さから、引き継ぎ先のチームがDDDに対する理解をしていることもあまり期待できないのではないかと思います。
この文脈移譲の難易度もまた、コミュニケーションコストが高いと僕が感じる要因の一つになります。
4. 探索的開発ではBounded Contextが変わりやすい
DDDにおいて、Bounded Contextの定義は設計の中心になります。
この業務コンテクストの境界はどこか、このドメインモデルの責任はどこまでかを定義することで、それぞれのドメインにどこまでロジックを凝集させるかが決まり、その範囲内で改修・増築を加えていくことで、モデルに対してドメイン知識が集まっていきます。
しかし、探索的にアジャイルを回し、ユーザーの価値がどこにあるか、どういった機能をユーザーが必要としているかを探していくスタンスで開発を続けていくと、ここだと思った境界が実はずっと広かったり、ここが中心になると判断したコアドメインが実は思ったよりずっと小さい優位性しか発揮できていないことがあります。
探索的なプロダクト開発では、検証を行うことで見えていなかった課題や価値を発見していくことが目的となります。 つまり、プロダクトの基本的な設計を行わなくてはいけない段階では、まだCore Domainはおろか、プロダクトの目指す方向性やカバーする業務領域が見えていないことも多いのです。
DDDではドメインへの理解が深まるごとにコンテクストを見直すこと、ドメインを分割することを決して否定してはいません。むしろ推奨しています。
設計思想としては柔軟性をかなり重要視しており、知見や解像度が深まるごとに柔軟にモデルやBounded Contextを変更できるはずなのです。
しかし、毎週のようにリリースを行い、検証ごとにどんどん新しい知見が発見されるアジャイル開発において、週次や隔週でのコンテクストの見直しや分割・リファクタリングは非常にコストが高く、またドメインに対する知見が必ずしも深まるわけではない(むしろ捨てるという判断もかなり多い)ため、開発初期から仮説上のBounded Contextに基づくモデル設計を固めることはなかなかにコスパが悪いことが多いです。
探索的な開発を行っていない、もしくはある程度決められたコンテクストの中で探索的活動を行う場合はこの限りではありませんが、それでも事前に業務の全てを知ることはできません。
僕自身、そういった開発スコープの中でも何度もリファクタリングやコンテクストの分割・統合を繰り返してきました。
生成AIが全盛期になった昨今では、探索的開発のイテレーション速度も急激に向上しています。
急速な作っては捨て、作っては捨てを繰り返す中で、初期仮説に基づくBounded Contextをコードやモジュール、データベース、サービス境界として早期に固定してしまうことは、チームのアジリティにも大きく影響します。
マイクロサービスアーキテクチャの話でもよく言われることですが、Core Domainや周辺ドメインとのBounded Contextがわからないうちはあまり積極的に採用しない方がいいのかもしれません。
しかし、MSAは境界が見え始めてからサービスを分割するという手法が取れる一方、DDDはビジネスコンテクストをドメインモデルに凝集させることに価値があるともいえ、ある程度アプリケーションのアーキテクチャや各レイヤー設計が決まった後からモデルとして表現し直すというのは非常にコストが高く、タイミングの見極めが非常に難しい設計手法でもあると考えています。
探索初期の段階において、どこまでBounded Contextを定め、どこまでモデルや設計に知識を凝集させるか、また議論を行うかといった投資判断は非常に難しい課題だなと考えています。
2つの探索的活動について
また、この記事を生成AIにレビューしてもらってる中で、以下のようなフィードバックをもらいました。
ここでは次の2つを分けると非常に良いです。 Domain Discovery: 存在している複雑な業務を、より深く理解する。 Product Discovery:どの問題を、どのような製品で解くべきかを検証する。 DDDはDomain Discoveryと非常に相性が良い一方、Product Discoveryの初期段階でコードレベルまで高いモデリングコストを払うと、その機能や仮説ごと捨てる可能性があります。
アジャイルによる探索をずっと続けてきましたが、この視点からDDDを見たことがなかったので追記させてください。
確かに複雑な業務やカバー範囲を理解するための探索と、プロダクトとしての価値を見出す探索が二つあるのは事実であり、実際にDDDの有用性を実感できたケースは前者が多かったように感じます。
Twitterではweb系では使い物になるが、基幹業務では使い物にならないという議論を見たことがありますが、むしろ基幹業務、中でも独自の複雑な業務ルールに競争優位性が存在する基幹領域こそDDDが最も活きる場所なのかもしれません。
特にDomain Discoveryのようなケースでは、話を聞けるドメインエキスパートが基本的に存在し、開発チームも比較的業務に対する知見や解像度が高いことが多いため、ドメイン設計やBounded Contextの探索にかけたコストが無駄にならないことが多かったように思います。
一方、Product Discoveryにおいては、まだドメインエキスパートがいないケースや、ユーザーがドメインエキスパートの役割を担うことが多く、継続的なユースケースのヒアリングを行うことが難しかったり、そもそもまだこの世に参考になるユースケースが存在しないこともあります。
プロダクトの方向がまだ決まらない、追求する価値が定まらないといった段階で、Bounded Contextの判断やモデルに対してどこまで知見を凝集するかといった投資判断は変わらず難しいところではあるなと感じます。
また、この二つが組み合わさった、業務効率化の際もコストパフォーマンスの判断が難しいなと感じる部分があります。
前職でSaaS開発をしていた時もそうでしたが、コンサルの業務では顧客の業務を棚卸し・交通整理しながら新しい機能や業務フローを構築することがかなりあります。
そういった場合、棚卸し・交通整理の段階でBounded Contextとそのコード表現を固め過ぎてしまうと、逆に実態を見誤ることが多々あります。
なお、Domain DiscoveryやProduct Discoveryといった単語はDDDの専門用語ではなく、探索的開発で使用される言葉ですね。
弊社でもDiscovery Phaseという名前でそれぞれの探索を行うことがありますが、業務を深掘りしていくDiscoveryと価値探求のDiscoveryは分けて考えることが多いです。
5. 日本語でのユビキタス言語とプログラムの相性がとにかく悪い
このトピックは主に日本人開発者向けの内容になります。普段から英語でドメインエキスパートやチームメイトと会話している方は読み飛ばして構いません。
あまり日本のDDD議論の中で主眼になることがありませんが、「ユビキタス言語」はDDDにおける最も影響力の大きい発明品であることは間違い無いかと思います。
ユビキタス言語があるからこそ、業務上で使用される言葉がコードとして表現可能になり、ビジネスの文脈とエンジニアリングの文脈が分断されずに会話することが可能になります。
ユビキタス言語のないDDDはそもそも表現する対象を持たないため、DDDですらないとすら言えるのではないかと考えています。
しかし、残念ながら日本語でクラスや関数を定義することは実際の現場ではほぼあり得ません。(僕は一部のテストコードでのみ見たことがあります。)
また、古くからのプロダクトではしばしばkeiyakuやKyuryouなどの日本語変数や日本語テーブルを見ることがありますが、基本的にほとんどのプロダクトは英語を使用して書かれていると思います。
英語もしくはアルファベットで表現される言語を使用している場合、コード上の表現とビジネス上の言語を一致させることが比較的容易ですが、日本語はそのままコードに変換することはあまりなく、一度英語を経由する必要があります。
例えばビジネスでよく使用される「差し込み対応」のような言葉を表現する際、そのままsashikomiという言葉を使うことはあまりなく、多くの場合prioritizeやexpediteといった言葉に変換されるのではないかと思います。
この場合、ユビキタス言語を構築しても、そのユビキタス言語と対応する英語の間にまたglossary、つまり翻訳レイヤーを作成することになります。
本来ビジネスエキスパートとエンジニアの間での翻訳レイヤーを減らすためのユビキタス言語であるはずが、さらに別の翻訳レイヤーが発生してしまうことで、認知負荷が上がるとさえ感じる時もあります。
また、副次的なデメリットとして、ビジネス上の言語表現になるべく英語表現を寄せようとした結果、英語圏ですらあまり使われない単語やあまり自然ではない言い回しをしてしまうことがあり、どこまで機械表現を許し、どこまでビジネス表現に寄せるかも非常に判断を問われることが多いなとも感じています。
DDDはモデルにおける言語表現とビジネス上の言語表現の一致に価値を見出し、ユビキタス言語に存在しない言葉をエキスパートから聞き出すことでビジネス上の未知を検知する手段としても使用できます。
つまり、コード上の表現とフローを理解し、コード上の英語表現を頭の中で日本語のユビキタス言語と結びつけることでやっとエキスパートと会話できる、ではあまりユビキタス言語のメリットを享受できないのです。(これが日本であまりユビキタス言語が議論されない大きな要因ではないかとも考えています)
ドメインエキスパートとの会話を英語で行い、またチームメイトとの会話も英語であり、英語を読み書きすることに全く苦がない場合はあまり問題になりませんが、そういったチームやプロダクトは、日本ではほぼないのではないかと思います。
6. ドメインエキスパートとの対話が実現しないことが多い
繰り返し述べてきましたが、DDDはドメインエキスパートとエンジニアの会話が設計の中心になります。
つまり、エンジニアはユーザーやビジネスサイドの人間とのフロントに立ち、同じ視座で会話することが求められます。
これはアジャイルでも同様のことが推奨されていますが、いまだに現場に足を運ぶエンジニアはあまり多くないように思います。
ビジネスサイドやユーザーとエンジニアが対話するのを忌避するPMや営業担当もまだまだたくさんいるという話は聞きますし、現職でもある程度の信頼を得られるまでビジネスサイドとの直接の接触を拒否されることは多かったです。
最近になってFDEという職種にスポットが集まり始めましたが、これまでエンジニアは会社や自室に籠り、チームメイトとだけ会話し、ビジネスサイドとは必要な場面を除いて会話をしないという組織が多いのではないでしょうか?
現職は本社の社是として客先にいけ、ユーザーと話せ、顧客と対話しろと繰り返し教わるため、僕自身コンサルタントとしてどうクライアントの方々から信頼を勝ち取りユーザーやドメインエキスパートと話す機会を得るかに非常に苦労しました。
これは単純にエンジニアがコミュニケーションを嫌うというよりも、組織的な問題であることも多く、DDDを正しく実現するためには組織や業務そのものを変革していく必要があり、非常に難易度の高い仕事になります。
また、ドメインエキスパートが必ずしも自分たちのために時間を割いてくれるとも限りません。
ドメインエキスパートにはドメインエキスパートの仕事があり、ソフトウェア開発は必ずしも彼らにとって優先順位の高い問題ではないことが多いです。
彼らにとって自分たちの開発しているソフトウェアは彼らの業務にとって有用なものであり、作っている自分たちは信頼に足る存在だと認識してもらうこと、そしてその上で彼らの工数をソフトウェア開発に使うことを組織として許容してもらうこと。
これらは開発チーム単体で決められることではなく、ステークホルダーも非常に多くなるため、多くのコミュニケーション、価値のアピール、工数の交渉が必要になります。
つまり、DDDを採用するということは自分たちの設計手法や働き方を変えるだけでなく、組織に対してもソフトウェアへの投資を呼びかける必要があり、そう言ったコストや手間も惜しまない姿勢が求められます。
7. 地味に生成AIとも相性が悪い(と感じる)
これは僕の使い方が悪いだけな可能性もあるのであまり強く主張するつもりはないのですが、生成AIに対してコードの生成依頼を出す際に、ビジネスコンテクスト、コンテクスト境界、モデルの表現方法、ユビキタス言語など、多くのことを共有する必要があり、トークンの使用量・プロンプトを書き上げる時間が想像以上に嵩むなと感じることが多くあります。
逆に、雑にこういう要件でこの機能を実装してのように頼んでしまうと、CRUDだけを達成する貧血モデルが増えたり、コンテクスト境界を乗り越えたコードを書いてしまったり、メソッドやモデル名が機械的になり過ぎてしまってモデルがビジネスを表現しなくなったりしてしまうことが多々あります。
LLMはある程度リポジトリ内のコードを参照して実装を行ってくれるため、ストレートな機能要件の実現だけであれば問題はないのですが、DDDとしての価値を実現するためにはある程度の暗黙知の言語化が必要になります。
当然他の設計手法を採用してる場合もある程度のコンテクスト共有は必要になります。
しかし、他の設計手法、特に単純なMVCなどで書かれたCRUDベースのコードを書く場合、僕は自身の頭の中にあるコードをそのまま指示として書き出してもらうケースが圧倒的に多いのですが、DDDを採用してる場合はコード上の表現を相談しながら書くことが多いです。
この相談に対する回答が的外れにならないためにも、同一のドメイン知識と設計意図を踏まえた上でで彼らと話す必要があり、それなりにコストがかかるなと感じています。
これらはコンテクストマップの作成やビジネスコンテクストのドキュメント化、CLAUDE.mdなどの指示ファイルや再利用可能なルール・スキル化などである程度乗り越えられますが、一方でドキュメントそのもののメンテナンスコストも高まるほか、必ずしもそのドキュメントを正しく参照・理解してくれるとも限りません。
最近はある程度雑に書いてもらった後、徐々にコンテクスト共有とフィードバックをしながらモデリングを行うようにしていますが、DDDを採用していなければここまでの議論は本来不要だったのかもと感じることも多くあります。(そのおかげで自分のドメイン理解を繰り返し言語化する機会が増えるので、あながち悪いことばかりでもないのですが)
8. どのようなチームやプロダクトでいつDDDを採用すべきなのか
さて、まとめに入っていきたいと思います。
では、このような難しさやコストの高さを抱えるDDDは、どのようなチームやプロダクトでいつ採用するのが正しいのでしょうか?
まずは課題を整理し、その上でどのようなプロダクトで採用すべきか、またどのタイミングで導入するのが効果的なのかについて書いていきたいと思います。
DDDの課題についてのまとめ
それぞれの章で挙げた課題を列挙すると以下のようになります。
- DDDは教育・学習コストが高すぎる
- DDD自体が難しい概念であり、理解するのに学習と実践による習熟が必要とされる
- チームのメンバーがDDDについてある程度の共通認識を持つまでの教育・学習コストをペイできる必要がある。
- チーム内のコミュニケーションコストが跳ね上がる
- ビジネス的な価値の議論が増えると同時にDDDとしての正しさや実装詳細に関する議論が増える
- 文脈移譲にも大きなコストがかかる
- 探索的開発ではBounded Contextが変わりやすい
- 探索的プロダクト開発の初期段階ではBounded Contextが見えづらい
- 仮説段階で実装を固め過ぎてしまうとコスト回収ができずに捨てることが増える
- どの段階でどこまで設計や実装を固めるかの見極めが難しい
- 日本語でのユビキタス言語とプログラムの相性がとにかく悪い
- 日本語で発せられるビジネス用語を英語に書き直すことで翻訳コストが発生する
- 英語によるコード表現と日本語でのビジネス表現を頭の中で一致させる必要がある
- ドメインエキスパートとの対話が実現しないことが多い
- ドメインエキスパートの仕事はソフトウェア開発ではない
- 協力を得るには信頼と組織的な支援が必要になる
- 地味に生成AIとも相性が悪い(と感じる)
- チーム内や顧客との間の暗黙知をAIにわかるよう言語化する必要がある。
- 暗黙知の言語化にはコストがかかり、継続的にメンテナンスしていく必要がある。
どんなチームやプロダクトで採用すべきか
基本的に僕は多くのチームではDDDはなかなか採用が難しい設計理論だなと考えております。
前述の課題を全てカバーできるようなチームやプロダクトがどれだけあるかと考えた時、少なくとも僕は体感として、実は1%も存在しないのではと感じるようになりました。
これがタイトルで99%の開発チームにはDDDは向かないと書いた根拠になります。
ただ、一部のプロダクトではDDDで作った方が良かったかもしれないと感じたものやチームがあったので、その点について書かせていただきます。
まず、第一に事業会社やSaaSベンダーなどのプロダクトで、自社のエンジニアチームで長期的に保守運用されるプロダクトには向いているかもしれません。
外注だから悪いというわけではないのですが、僕のようなコンサルタントが担当するプロダクトは多くの場合単価との兼ね合いから、長期的な開発と運用を見込めることは多くはありません。
在任期間は長くて2~3年程度となり、せっかく積み上げたビジネス上の知見や複雑さへの対応も、いずれは保守ベンダーに流れる定めとなることが多いです。
逆に、自社のエンジニアチームでの開発・運用が前提となる場合、コード上に表現されたビジネス上の知見が、エンジニア・ドメインエキスパートの中である程度断絶されることなく共有され続けるという点はDDDと非常に相性がいいように思います。
また、通常パートナーであるコンサルやSIerなどのエンジニアに対してクライアント側が教育・学習コストを払うことはありませんが、自社のエンジニアチームであればある程度許容されることも多いかと思います。
DDDは学習・教育コストが非常に高い設計手法のため、短期間で離任する可能性が比較的低いインハウスのエンジニアであればある程度教育に対する投資効果が見込める可能性があります。
次に、その上でという条件になりますが、業務領域に変化はあるものの完全になくなることが少ない領域をカバーするプロダクトであることが挙げられます。
「Bounded Contextが変わりやすい」でも述べた通り、関心領域を移り変える・ピボットの可能性もあることが前提の段階で、あまり深くDDDにこだわりすぎると、DDDのメリット以上にリファクタリングやユビキタス言語の再整理、認識の再構築にコストがかかりすぎる可能性があるためお勧めはできません。
一方で、既存の業務をシステムに置き換えるもしくは既存システムをリプレイスするといった場合は、ドメインそのものが消失する可能性は非常に低く、業務フローの変更などを考慮した上でも、DDDのメリットを十分に享受する土台はあると言えるかもしれません。
そういう意味では、日本でDDDが議論の俎上に載るのはスタートアップやSaaS企業などがあまりに多く、基幹システムを担当する方々からあまりDDDの話が出てこないのは非常にもったいないなと感じています。
また、チームの置かれている状況も非常に重要になります。
望ましい条件としては、前述のある程度長期間固定される可能性の高いことに加え、DDDへの理解が十分にありユビキタス言語やモデリングの構築を主導できる人物が少なくとも一人、可能であれば複数いること、その上で開発チームとビジネスチームが分断されていないこと、また英語と日本語での言語表現と変換が柔軟にできることが挙げられます。
特に最初の条件はかなり重要だと考えております。
なぜDDDは自分たちのプロダクトに有用なのかをチームや組織に対して説明できること、DDDに馴染みのないメンバーのリードができること、モデリングを主導・レビューができることと言った条件を兼ね備えた人物がいない場合、DDDは冗長でコード量が多く意図が伝わりにくい設計に成り下がります。
また、Tactical DDDの表層だけを再現した設計になった結果、逆にDDDに知見がある人が途中からジョインした際に困惑してしまう可能性も十分に考えられます。
アジャイルを始める際には必ず経験豊富なアジャイルコーチやスクラムマスターを雇えと言われますが、同様のことがDDDにも言えるかと思います。
いつDDDを導入すべきか
いつ導入すべきかに関してですが、僕の中でこのタイミングの判断が非常に難しいなと考えています。
まず前述の通り、関心対象が大幅に移り変わるようなフェーズでは明らかに向きません。
大前提として、DDDは理論上それを可能である、むしろそう言ったプロダクトに向いている設計ではあるのですが、現実問題として前述したように、大規模なBounded Contextの見直しやそれに伴うリファクタリングは非常に大きなコストがかかるため、少なくとも僕の体感としてはあまり向かないように思います。
また、長年メンテナンスされ続けたプロダクトの一部だけを実験的にDDDに置き換えるようなこともおそらく向いていないことも多かったように思います。(※生成AIからの反論FBを後述しています。)
これはDDDに限った話ではないのですが、基本的に設計パターンがコードの一部だけ変わると、他のモジュールとの整合性が取れなくなったり、そもそもコードとしてのまとまりを把握するのが困難になることがあります。
ボクはおそらく途中からDDDに切り替えたのであろうプロダクトをいくつか見たことがありますが、担当者がいなくなったものも多く、志とDDDに関する憧れは感じつつも、完全なDDD移行はされないまま不純物としてレポジトリに残っているものも多くありました。
一方で、DDDを採用して良かったと思うタイミングもいくつかありました。
まずMVPまでの検証が終わっており、ある程度どこにCore Domainの所在があり、どこにcontext boundaryを置くべきか見えてきた段階です。
MVPやプロトタイプの段階からあまり深くDDD的なアプローチをすると、サンクコストとしての捨てるモデルやコンテクストが大きくなるのは前述のとおりです。
捨てる可能性のある領域とそのまま拡張していける領域を比べた際に、最もバランスのいいタイミングは、MVPの検証、特に一つのMVPではなく複数のMVPを検証した上で、ある程度方向性が見えた段階だと考えています。
現職で実際に行った課題解決のフレームワークとしてデザインスプリントという取り組みがあるのですが、1週間で1つの課題に対するアイデア出しからプロダクトを作成、ユーザー検証を集中して行う若干長めのハッカソンのような取り組みを繰り返し行います。
この検証が終わった段階では、どんなユーザーに対してどのようなプロダクトを作るかはある程度はっきりしています。
ドメイン領域と競争優位性の所在がある程度はっきりしており、その複雑性をDDDにより表現すること、またそこに対する投資によりコード上の柔軟性を確保できることは、DDDのメリットをかなり活かしやすい環境だったようにも思います。
自分としてはその時点でDDDに対してかなり懐疑的であったのもあり、あまりDDDに対する知見は活かしきれたとは言えないのですが、実装しながらここは本当にDDDで良いのかもしれないと思えた久しぶりの体験でした。
また、既存の業務をシステムに置き換える行為そのものが十分な競争優位を生むものも、またDDDと相性がかなりいいなと感じました。
メイカーや小売のようなサプライチェーン管理などがわかりやすいですが、複雑な仕入・発注・納品・検品などの業務フローそのものが他社に比べて競争優位性を実現していることが非常に多くあるかと思います。
一方でそういった業務フローは、ERPやSaaSでは対応し切れない独自性や言ってしまえばクリエイティビティに溢れており、そう言ったフローをただのCRUDシステムとして表現するのは難しく、DDDがかなり活きる場面だと考えています。
つまり、基幹業務としてそのフローそのものが他社との差別化を図れるプロダクトに関して言えば、かなりDDDと相性がいいと言えるかと考えています。
自分も含めコンサルタントはえてして業務の効率化の名の下に業務フローを変えようとする傾向にありますが、実はその業務フローそのものが企業価値を生んでいることも多々あります。
これは自分としてはDDDを学んだエンジニアとして基幹システムに関わった故に得られた知見だなと感じています。
※ 生成AIにレビューしてもらっていた際、Evans自身がこう言った課題に対して、GETTING STARTED WITH DDD WHEN SURROUNDED BY LEGACY SYSTEMSという記事を出していることを知りました。 この記事の中では、既存システムの周辺に小さなコンテクスト境界を作成し、その範囲で漸次的にDDDを導入していく手法が書かれています。 ここに関しては、新規の機能開発対象のコンテクストのみに適用するという、近しいことをやったことはありますが、本記事に基づく実践経験がないため是非を語ることは避けたいと思います。 ざっくり読んだ感想としては、言いたいことはわかるが、実践するのはまたさらに追加のコストと経験が必要だなと感じました。 今後またレガシーシステムに対してDDDを適用する機会があれば、是非試してみたいですね。
(余談)今後もしかしたらDDDを採用すべきプロダクトが20%くらいになるかもしれない点について
さて、ここまでDDDを採用すると言う難しさと、非常に厳しい条件下でこそDDDが生きると言う話をしてきました。
ただ、自分としては今後DDDは生きる機会が非常に増えていくと考えています。
まず、世界的な傾向としてSIerやコンサルタントにソフトウェア開発を委託せず、内製化を進める企業が増えている点です。
前述のとおり、外注を基本的な開発運用の前提としたプロダクトには、DDDは圧倒的に向きません。
一方で、自社の業務を理解した自社の組織に自社のプロダクトを開発・運用させたいと言う企業も増えています。
これはTwitterやニュースを見てるだけではなく、可能性の一つとして転職を視野に入れている自分としてはかなりリアルに感じられます。
LinkedInでは、誰もが知る大手企業がDXを主導するエンジニアが欲しい、内製化をリードして欲しいというスカウトメールが暇もなくやってきます。
自社の基幹戦略としてプロダクト開発を自社内で進め、その上で自社で運用していこうと言う流れは、DDDにとっては大きな追い風のように感じます。
こういった追い風の中で、ドメインエキスパートとのコミュニケーションハードルの低下やメンバーへの学習・教育コストへの受容、また自社ドメインゆえのコンテクストの変わりにくさと言った部分で、半分以上の課題は徐々に解消されていく可能性は十分にありえます。
また、生成AIの台頭も、記事内でそれを否定した身ではありながら、非常に追い風だなと感じています。
生成AIは暗黙知の言語化を必要とする追加コストを負いながら、一方で言語化をかなりの精度でアシストします。
枚挙に暇がない話ではありますが、ドメインエキスパートとのweb meetingのdictation、喫煙所で聞いた現場からの情報、飲み会で聞いたユーザーへの熱い思い。 そう言ったものを自身で噛み砕きながらLLMに流し込むことで文書化はかなりスムーズに進む可能性が高いです。(炎上したくないので一応補足しますが、組織に許可されたsandbox環境でこそなのは言うまでもないです。)
暗黙知の文章化、その意図をコードとして表現することは、意外にLLMと相性がいいなと感じる部分もあります。
LLMがトークンとコンテクストを前提に動いている以上、どの話題を捨ててはいけないか、逆にどの話は聞き流していいかの判断を非常にシビアに問われるので、それなりに難易度の高い作業になりますが、その時点で見出されたBounded Contextとあるべきモデリングの刷新を続けていくには必要な活動かなと考えています。
これが現状ほとんどのチームに向かないと考えてる自分が、もしかしたら今後20%くらいまで上がっていくかもなという感想を最近持ち始めた理由になります。(特に数字への根拠はありません。)
最後に
この記事で書きたかったのは、DDD自体は強力な設計手法でありながら、その実行には非常にたくさんの課題や困難が存在するということです。
タイトルにもある通り、僕は現在もDDDを採用するかという問いに関しては、かなり懐疑的な視線を持っています。
特にDDDを理解したエンジニアを一定数以上チーム内に採用・育成するというのは本当に難易度が高く、またAIの助けがあってもなかなか解消されるものではありません。
一方で、正しいタイミングで正しく使えば強力な設計思想であることも上述の通りです。
この記事では繰り返し投資という言葉を使用してきましたが、DDDの採用は技術的判断でもあり、大きな投資判断でもあると最近は考えています。
書籍やブログなど、DDDのメリットや実践的手法に関する文章は多く存在しますが、実務に登用すべき時に重要なデメリットはあまり語られません。
しかし、DDDの採用にあたっては、大きなリファクタリングコストやメンバーへの学習・教育機会のコスト、また特に初期起きがちな大幅なコミュニケーションコストの増加を受け入れる必要があります。
一方でDDDを採用することで得られるメリットはこの記事で書いた以上に多く存在します。
現状DDDはまだまだ主流な設計手法であり、今後も多くのプロダクトで採用されていくことだと思いますが、そんな時ここで書かれたことが一つの判断基軸として役立つことを期待して、この記事は締めようと思います。
最後まで読んでいただきありがとうございました!








