👻

ドメイン駆動設計の正体

2023/10/20に公開

はじめに

"ドメイン駆動設計は当たり前のことを言っているだけ"
"ドメイン駆動設計はただのオブジェクト指向プログラミング"
"ドメイン駆動設計はより良いアーキテクチャだ"
"軽量DDDはアンチパターンだ"

このようなドメイン駆動設計に関する言及を聞いたことがあるでしょうか?
ドメイン駆動設計に言及する記事や書籍は多くありますが、それぞれ着目する側面が異なったり色々なコンテキストから言及されています。
おそらくそれが原因でドメイン駆動設計が何であるかをぼやけさせ、正体のわかりにくい概念になっているように思えます。
そこで今回は色々な観点から整理し、ドメイン駆動設計とは何であるのか、その正体を考えていきます。

ドメイン駆動設計の基本的概念について

ドメイン駆動設計はEric Evansが出版した「Domain-Driven Design」という書籍がルーツになっています。
ドメイン駆動設計を一言で表すと「より良いソフトウェアを開発するために、そのソフトウェアが対象としているもの(ドメイン)を中心に考えて開発を進めようとする開発手法の一種」などになるかと思います。

ドメイン駆動設計は大きく分けて下記の2つの概念に分解することができます

戦略的設計

ドメイン駆動設計の根本となる思想を含み、開発者と関係者で同じ言葉(ユビキタス言語)を用いることで認識齟齬を減らし改善のループを回しやすくしようという提案やシステムをどのように分割するべきかという指針が示されています。
キーワードとしては、ユビキタス言語、サブドメイン、境界づけられたコンテキストなどが含まれます。

戦術的設計

戦略的設計を達成するために、具体的にどのように実装するかというテクニックを示しています。
近年では、戦略的設計を取り入れず、戦術的設計のみを取り入れることを軽量DDDと表現されることがあります。
キーワードとしては、Entity、Value Object、Domain Service、Repository, レイヤードアーキテクチャなどが含まれます。

なぜドメイン駆動設計は生まれたのか?

ドメイン駆動設計の誕生の経緯を考えるためには、いつ世に出たのかということに注意して考える必要があります。
「Domain-Driven Design」が出版されたのは2003年です。

2003年と言われてもあまりピンとこないかもしれないので、その頃にソフトウェア工学の文脈であった主要な出来事を記載します。

  • 2001年: アジャイルソフトウェア開発宣言
  • 2002年: Patterns of Enterprise Application Architecture(PoEAA)出版
  • 2004年: Ruby on Rails、SOLID原則

これを踏まえると、ドメイン駆動設計が登場した当初は、このような時代だったと考えられます。

  • アジャイル的な考えが出てきたものの、ウォーターフォール的なフェーズに分けられた開発方法がまだ多く採用されていた可能性がある。
  • Ruby on Railsのような主要フレームワークもまだ存在せず、PoEAAに代表されるようなパターンを用いて実装を行なっていた。

texta.fm[1] ではドメイン駆動設計以前の課題とそれをどう解決しようとしたのかについて下記のように言及されています(端折って記載しています)

  • 分析、設計されたモデルと実装されたコードの乖離
    • 要件定義 → 分析 → 設計 → 実装 → テストといったフェーズに分かれていた開発を行なっていた
    • 分析者が実装のことをできる限り考えず抽象化してモデルを作ることが良しとされていた
    • 実装と乖離していき、開発で得られたフィードバックをモデルに還元できない
    • アジャイルがアンチテーゼにしていたものとEric Evansがアンチテーゼにしていたものはある程度一致する
    • ドメイン駆動設計では、実装で得たものをモデルにフィードバックしようという考え方を提案
  • ビジネスサイドとエンジニアの乖離
    • ビジネスサイド、ドメインエキスパートが話している言葉とエンジニアが書くコードにズレがあった
    • ドメイン駆動設計では、チーム全員で利害関係者が同じ概念に対して、同じ名前を与えてそれをコードまで反映させて開発しましょうということを提案

これらの問題を解決するために、ドメイン駆動設計では当時よく使われていたPoEAAで紹介されているような設計パターン[2][3]を用いて戦術的設計を提案したと考えられます。

ドメイン駆動設計の歴史

ドメイン駆動設計は現在に至るまでに、流行の波が存在していたようです。[4]

「DDD難民に捧げる Domain-Driven Designのエッセンス」には、2007年は以下のような状況だったと記述されています。[5]

しかし、日本では翻訳書がいまだに出版されていないこともあり、本書の出版から3年近く経った今でも、まだまだ一部の通の人たちにしか広まっていないように筆者には思われます。また、原書を読まれた方の中からも「本が分厚すぎて読みきれない・・・」という嘆きの声も聞かれます(DDD難民という言葉もあるそうです)。

Googleで勤務されていたRohit氏は2010年ごろの状況について以下のように記述されていたようです(現在、原文は閲覧できない状態になっていました)

Eric Evans が独創的な著書 Domain Driven Design ( DDD ) で作成したドメイン駆動設計の理論は、2003 年 8 月 30 日に出版されました。 ... 現時点では、ほとんどのソフトウェア エンジニアはドメイン駆動設計の戦術的および戦略的パターンを適用するのにまだ苦労しています。これが2010年頃のDDDの状況でした。

このように書かれているように、当時はある程度注目されていたものの浸透するには至っていなかったようです。

2011年には、「Domain-Driven Design」の翻訳版である「エリック・エヴァンスのドメイン駆動設計」が日本で出版されます。和訳が出るまで8年の期間を要した理由として、丁寧に翻訳する必要があったため時間が掛かったと texta.fm で語られています [1:1]

また、さらに同ポッドキャストでこの辺りの時代に関して面白い言及がされています。
「2013年にピアソンショック[6]と呼ばれる出来事があり、多くのオブジェクト指向分析設計(OOAD)関連の書籍が絶版になり、そもそもOOADという概念が知らない人が増え、世代間の断絶が起きてしまった。
それが原因でOOADを扱う書籍として目立つものが「エリック・エヴァンスのドメイン駆動設計」ぐらいになってしまい真理を語る本として異彩を放つ本になってしまった[7]」と語られています。

こちらの記事[8]でも、これにおそらく関連するであろう言及がされています。

肝心のモデリングする部分が「ドメインエキスパートに聞いてコードに書いて洗練する」とか程度で方法論として薄いなぁ、というのも今までDDDに持っていた不満ポイントでした。
が、DDD本の出版当時に多数あった「既存のモデリング手法」をスケーリングさせるパターンであった考えれば、理解できます。問題は、20年ほど前に流行ったさまざまなモデリング手法が現代で失われてしまったということぐらいですかね。

私が初めてドメイン駆動設計を知った時は、まさにこのような感覚がありました。
OOADのような概念をほとんど知らず、「エリック・エヴァンスのドメイン駆動設計」の分厚さも相まって当時は何かとてもすごい本のように感じた記憶があります。

その後、2010年代前半には、境界づけられたコンテキストがマイクロサービスの分割の観点で再注目されその後、マイクロサービスの文脈とは別に2020年前後で日本でドメイン駆動設計に関する言及が増えたようです。

先の記事では下記のように言及されています。

そして多くのフレームワークはRails wayほど道が整ってなく、 多くの設計は自分自身が行う必要が出てきます。[9]

これは私の実体験とも一致しており、例えば、2017、18年ごろにはGoでのドメイン駆動設計を意識した記事がいくつか存在します。 [10][11]
GoにはRailsのようなフレームワークが主流ではないこともあり、まさに言及されている通り、その代わりの設計として注目された側面があるのではないかと考えられます。

また同時期に軽量DDDに関する言及も増えているように思います。
これも、Railsのようなフレームワークの代わりとなる設計を求めている開発者が多かったため、ドメイン駆動設計の戦略的設計の部分は不要に感じ、戦術的設計のみを取り入れた言及が多くなったことが理由ではないかと考えられます。
このような流れから、ドメイン駆動設計 = 戦術的設計という誤解をする人が増え、戦術的設計を原書からそのまま写しとることが良いことだという原理主義的な考え方が特に加速してしまった可能性があります。

ドメイン駆動設計をどう解釈するか?

  • ドメイン駆動設計以前の乖離の問題のうちの1つ「分析、設計されたモデルと実装されたコードの乖離」は現代においてはあまり意識することがなくなりました [1:2]

    • 特に日本のWeb系企業では、ほとんどの会社がウォーターフォールのようにフェーズに分かれるような開発はほとんど行われておらず、きっちり分析されたようなモデルはもう存在しないと思われます。
  • 原書に書かれている戦術的設計の多くはもう古いものになっています

    • 2003年ごろのJavaを基本としたPoEAAをベースに作成されており、多くの言語が開発された現代ではもうそぐわないものも多くあります
    • そのため、原書を原理主義的にそのまま写し取ろうとするのは良いことではなく、現代にあった形を模索していくべきでしょう[12][13][14]

つまり、現代においてドメイン駆動設計は根本の思想には一定の価値があるものの[15]、戦略的設計、特に戦術的設計に関しては現代にはそぐわないものも多くなってきているので、大々的に導入するようなものでもなくなっているのではないか、というように個人的には思います。[16]

また、ドメイン駆動設計とは裏腹に、PoEAAで紹介されているTransaction Script[17]や、密結合であることを許容し開発速度向上を目指したRuby on Rails[18][19]は近年、少し過小評価されているようにも思えます。

最後に

この記事によって、かつての私のようにドメイン駆動設計を追いかけて、変に沼に嵌ってしまう開発者が1人でも減れば幸いです。

はじめに、で触れたいくつかのドメイン駆動設計に関する言及について再度触れましょう。

「ドメイン駆動設計は当たり前のことを言っているだけ」

これは原書が出た2003年時点では当たり前でないことが多かったが、現代においては当たり前の状態になっているものも増えてきた、ということでしょう。

「ドメイン駆動設計はただのオブジェクト指向プログラミング」

これは誤っていますね。あくまで原書では戦術的設計をOOPで実現していただけで、実際はOOPだけに縛られません。
「Domain Modeling Made Functional」という書籍で提案されているように、関数型プログラミングを用いて実装することも可能です。[20]

「ドメイン駆動設計はより良いアーキテクチャだ」

これも誤っていますね。ドメイン駆動設計ではアーキテクチャを限定はしていません。

「軽量DDDはアンチパターンだ」

具体的なパターンから入ることで理解を深めることは重要だと思うので、勉強目的で古典的な戦術的設計を取り入れていくのは個人的にはありだと多いますが、原書の戦術的設計を原理主義的に崇めてしまうとアンチパターンと言えるでしょう。

P.S.

余談ですが、最近はオブジェクト指向プログラミングが指す言葉も曖昧になっているような気がしますが、本記事では、曖昧な定義のまま使用しています、、

2023/10/24 追記

現代においてドメイン駆動設計は根本の思想には一定の価値があるものの

と前置きしていましたが、

大々的に導入するようなものでもなくなっているのではないか

と締めを書いてしまったためか、「つまり、ドメイン駆動設計はもう古いし価値がないってことだよね」という旨のコメントをそれなりにもらってしまいました。
それは、本来私が意図していたこととは少しずれてしまっているので、補足させていただくと、
ドメイン駆動設計は今でも価値のある部分はある(開発者と関係者がユビキタス言語を用いて会話をすべきという点など)と思っています。(そしてこれらはかなり意識して実践しないとなかなか簡単にできることではないと思っています)
ただその上で仰々しい名前がついてしまっているかつてのドメイン駆動設計にこだわるのではなく、現代においても大事な部分は抽出し、現代においてそうでない部分は引き算したほうが良いのではないかという意図でした。

脚注
  1. texta.fm: 1. Software Development in 2003 ↩︎ ↩︎ ↩︎

  2. PoEAAには、Entity, Value Object, Domain Model, Repositoryなど、ドメイン駆動設計でよく見る設計パターンが収録されています。 ↩︎

  3. 余談ですが、PoEAAの著者のマーティン・ファウラーは「自分はパターンを考案したのではなく、当時の開発で使われていたパターンを PoEAA にまとめただけだ」と語っているようです。 ↩︎

  4. DDDになぜ失敗するのか - 歴史から見つめ直すDDD ↩︎

  5. DDD難民に捧げる Domain-Driven Designのエッセンス ↩︎

  6. https://scrapbox.io/iki-iki/ピアソンショック ↩︎

  7. 補足ですが、「真理を語る本」というのは文字のままの意味ではなく皮肉の表現だと思われます。 ↩︎

  8. ドメイン駆動設計の源流のPofEAAを読んでみる ↩︎

  9. https://zenn.dev/dorarep/articles/5133db3c7c4438#2020年ごろの日本でのdddブーム ↩︎

  10. Goのpackage構成と開発のベタープラクティス ↩︎

  11. Goのパッケージ構成の失敗遍歴と現状確認 ↩︎

  12. GraphQL と Prisma から考える次のN年を見据えた技術選定 では ドメインモデルをclassを用いずに表現することを提案しています ↩︎

  13. 【第1回・前編】 エンジニア和田卓人の今を形作る技術 ↩︎

  14. TypeScriptによるGraphQLバックエンド開発 ──TypeScriptの型システムとデータフローに着目した宣言的プログラミング ↩︎

  15. 開発する対象のドメインを意識し開発者以外の関係者も巻き込んで技術的な要素だけに閉じてしまわないようにするという観点 ↩︎

  16. 2023/10/24 追記 ↩︎

  17. PoEAAではドメインロジックの実装方法としてDomain Model, Transaction Scriptなどが紹介されています。これらはドメインの複雑化に伴って、機能追加のための労力の変化の仕方が異なってきます。 ↩︎

  18. Ruby on Railsの招待と向き合い方, ドメイン駆動設計のドメイン層を他の層から隔離するという観点の対比として挙げています。 ↩︎

  19. フロントエンドの観点からは、Next.jsなどで行われている最適化の恩恵を受けられないといった面でのデメリットはあるかと思います。 ↩︎

  20. 関数型プログラミングはオブジェクト指向プログラミングと必ずしも相反するものではないと思いますが、このように表現することをご了承ください。 ↩︎

BACKSTAGE Tech Blog

Discussion