「ドメイン駆動設計をはじめよう」を3回読んで学んだ事をまとめる
はじめに
直近の業務で「ドメイン駆動設計」を活用した開発があり、自分の知識をつける為に「ドメイン駆動設計をはじめよう」を数ヶ月前から読み始めました。
結論を先に書くと、とても良かった!
t_wadaさんが「今後 DDD について最初に薦めるのはこの本になりそうです」とXで呟いていましたが、自分も同意しています。
間違いなく自分もドメイン駆動設計の初学者こそ読んでほしい本だと思います。
自分はこの本を3回読みました。
1回目は純粋に業務で活用する目的で読み、2回目はプロジェクトで活用しているがうまく実用化できてなく、壁にぶつかり悩むたびに答えをもとめるタイミングで読みました。
そして、3回目はこの記事を書く為、もう一度読みました。
繰り返し書きますが、とても良い本です。
3回も読むと頭の中にある程度、インデックスが貼られてきて1回目よりも早く読めます。
しかし、実際の業務で活用できた事もあれば、あくまでも座学として学びに終わり、プロジェクトでは活きなかった事が当然でてきます。それはどの技術本でも等しくそうかもしれません。
しかし、この本で書かれている内容の「本質」の部分はドメイン駆動設計にかかわらず、これからエンジニアのキャリアとして大事な指針になると思い、改めて自分なりの言葉でまとめてみようと思います 🙏
この本は以下の章にまとまっています
第Ⅰ部 設計の基本方針
1章 事業活動を分析する
2章 業務知識を発見する
3章 事業活動の複雑さに立ち向かう
4章 区切られた文脈どうしの連係
第Ⅱ部 実装方法の選択
5章 単純な業務ロジックを実装する
6章 複雑な業務ロジックに立ち向かう
7章 時間軸でモデルを作る
8章 技術方式
9章 通信
第Ⅲ部 ドメイン駆動設計の実践
10章 設計の経験則
11章 設計を進化させる
12章 イベントストーミング
13章 現実世界のドメイン駆動設計
第Ⅳ部 他の方法論や設計技法との関係
14章 マイクロサービス
15章 イベント駆動型アーキテクチャ
16章 データメッシュ
結びの言葉
付録A ドメイン駆動設計の実践:事例研究
この記事では全部の章を細かく説明するのではなく、自分が重要と思った部分のエッセンスを抜き、自分なりの言葉でまとめてみました! 🙏
なぜ我々はドメイン駆動設計で開発を行うのか?
自分がエンジニア1年目~2年目(2017)の時は「ドメイン駆動設計」という言葉をそもそも知りませんでした。その頃ですとMVCフレームワーク(Ruby on Rails、Laravelなど)を使った開発が主流で、そこには疑問も抱かず、それが当たり前と受け入れて開発をしてました。
そこから4~5年になるとMVCフレームワークでの開発での苦労する部分が増えてきました。
いわゆるFatModel、FatControllerの問題や、MVCにRepositoryパターンを後から導入するなど、長く稼働しているサービスが大きくなればなるほど、この問題は顕著になり、変更を入れるのが大変でした。
しかし、1歩引いて考えると長く稼働しているサービスというのは、それだけ他社の同様のサービスよりも優位性があり、売上があり、生き残っている証拠です。生き残ってないサービスというのは上記の問題にそもそも遭遇せずに、サービスが終了しますし、こちらが大多数だと思っています。
その状況がある中で我々はドメイン駆動設計を選択し、開発を行うのでしょうか?
ドメイン駆動設計はまさに、他社サービスとの優位性を確立する為に、できるだけ速くリリースし、そして将来の仕様変更に耐えうる開発を実現する為にあります。
「ドメイン駆動設計をはじめよう」の付録Aの最後の筆者の以下の言葉がわかりやすいです。
つまりは、ビジネス要求は変わり続け、優先度の変更もしょっちゅうです。しかもすべては「できるだけ速く」です。そして、研究開発をする余裕はほとんどありません。このような状況でドメイン駆動設計を受け入れる事で、私たちはさまざまな複雑さに立ち向かい、事業に貢献するソフトウェアを生み出し続ける事ができました。つまり、振り返ってみれば、ドメイン駆動設計に賭けた私たちは十分な見返りを手に入れたのです。
誤解してほしくないのは「最初からドメイン駆動設計を導入すべき!」とは思ってないのと、それを推し進めたいとは思ってない事です。MVCアーキテクチャを採用する場合のメリット、デメリットがあるように、ドメイン駆動設計におけるメリット、デメリットも当然あると思っております。
したがって、「なぜ我々はドメイン駆動設計で開発を行うのか?」の問に対しては、運営しているサービスの性質があり、そのタイミングで向き合っている課題によって、ドメイン駆動設計を導入すべきは考えたほうが良いと思っています。
その上でドメイン駆動設計を採用すべきで悩んでいるなら、手を動かすまえにこちらの本を読むだけでもおおまかな概要が学べるので良いと思っています!
中核の業務領域こそドメインモデリングに取り込む
本書の「第1章 事業活動を分析する」で「中核の業務領域(Core Subdomain)」について、本では以下のように説明がされています。
中核の業務領域だけが競争優勢を生み出します。中核の業務領域は競合他社との差別化を図る事業戦略の核心です。
第1章で一貫して伝えられているメッセージの一つに「中核となる業務領域(Core Domain)を見極める」というテーマがあると思っています。これはドメイン駆動設計(DDD)を理解しようとするときに、最初のハードルであり、最も重要な考え方の一つだと感じました。
またこの中核の業務領域は頻繁に変更されます。
したがって1年前は中核の業務領域だったのが、1年後に外部APIに切り替えて競争優勢がなければ一般、または補完になります。
そういった意味でビジネスの競争優位性を生み出している部分の中核を見つけるために重要なのが「ドメインエキスパート」との対話であり、個人的にドメイン駆動設計というのは「対話」を通じて、どのような知識がビジネスの本質なのか?を発見し、それをモデルに取り込んでいくアプローチこそに最大の価値があると思っています。
ドメインエキスパートと対話し、「同じ言葉」を見つける
「ドメイン駆動設計をはじめよう」では何度も「同じ言葉」という説明が出てきます。
これはドメイン駆動設計をたらしめる核心とも言える考え方であり、「エンジニアがコードで使う用語」と「ビジネスサイドが会話で使う言葉」を一致させることを目指します。
自分が実務で感じたのは、「言葉の揺れ」がプロジェクトの不具合や誤解の原因になることが多いということです。例えば、「商品」と「製品」、「顧客」と「ユーザー」など、似たような言葉が複数ある場合、それぞれが何を指しているのかを明確にせずに実装を進めると、ある日突然ロジックが破綻することがあります。
この本では、ドメインエキスパートと定期的に会話するだけでなく、イベントストーミングなどの手法を活用し、言葉の整理と意味づけをワークショップ形式で行う重要性を語っています。また、言語が整理されることで、コードベースにもそのまま「意図」が現れるようになります。
クラス名、メソッド名、変数名にビジネス用語が使われ、それがドキュメント代わりにもなっていく。こうした設計をしておくことで、自分がプロジェクトを離れた後でも、後任のエンジニアがスムーズにキャッチアップできると感じました。
単純なトランザクションスクリプトの活用方法について
「ドメイン駆動設計」での実装を考えると、すべてを「ドメインモデルで実装する」と考えがちですが、本書ではトランザクションスクリプトの活用も戦略の一つとして紹介されておりここがとても良かったです。
特に第5章では、単純なCRUD処理に対してドメインモデルを無理に当てはめるのではなく、シンプルに手続き型で書いた方が良いケースを紹介しています。これは設計におけるトレードオフの良い例であり、すべてを「正しく」やろうとするあまり、逆に複雑性を生み出してしまう罠を避けるヒントになりました。
本の中では「トランザクションスクリプト」は補完的な業務領域に向いていると書いており、こういったのも取り入れて開発を行うのは本を読んで学ぶ事ができました。
ドメインモデルを活用して必要なAggregate、Entity、ValueObjectを用意する
本書の第6章・第7章では、いわゆる「リッチドメインモデル」の考え方、そしてその具体的な設計要素としての エンティティ(Entity)、値オブジェクト(ValueObject)、集約(Aggregate) の役割と使い方が丁寧に解説されています。この部分は、ドメイン駆動設と他の設計スタイルを分ける大きなポイントの1つでもあります。
ちなみに自分は1回目に読んだ時にはあまり理解できず、実際のコードがあると具体的な説明が入りやすいので、ここに具体的なAggregate、Entity、ValueObjectの活用方法については、コードを書いて学ぶと良いと思っています。
「はじめてのドメイン駆動設計」でも学べますが、個人的にはサンプルコードが多く記載されている以下の本もおすすめです
「ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本」
集約(Aggregate)に関してもう少し書くと、個人的にはドメイン駆動設計の中でも特に難解な概念でした。初めての頃は「とりあえず関連するEntityを1つのクラスに入れておけばいいのかな?」とやりがちだったんですが、プロジェクトが成長してくると、「一貫性をどこまで保証するのか?」という観点でAggregate設計の重要性がじわじわ効いてきます。
たとえば、受注システムで「注文(Order)」をAggregate Rootとした場合、注文の中に含まれる「注文商品(OrderItem)」や「支払い情報」などの変更をどこまで同時にトランザクションで扱うか? はパフォーマンスや整合性に直接関わってきます。この粒度をうまく調整することが、将来的な 変更耐性 や マイクロサービスへの分割 を視野に入れた設計につながる、ということがアーキテクトの腕の見せどころであり、難しい部分であると思いました。
常に複雑性と立ち向かう為に本質を考える
課題の合意なしに解決手法の話をしても無意味である。解決方針の合意なしに実現手法の話をしても無駄である。
エフラット・ゴールドラット・アシュラグ
この本を読み終わって一番心に残ったのは、技術論というよりも、「複雑性とどう向き合うか?」という、ソフトウェアエンジニアとしての心構えでした。
技術書によっては「こうやれば綺麗に作れる」といったベストプラクティスが紹介されますが、「ドメイン駆動設計をはじめよう」はそうではなく、「現実の業務は複雑だし、仕様も変わる。じゃあどうする?」という問いに対して、「現実の複雑さを直視し、ドメインエキスパートと対話を通じて、"同じ言葉"を見つけて、それをそのままモデルに取り込み、開発を行う」と真正面から答えているように感じます。
ドメイン駆動設計の本質を突き詰めれば、突き詰める程、開発手法ではなく、複雑な事業領域にどれだけ向き合うか?が大事だと思っています
だからこそドメイン駆動設計は、エンジニアだけではなく、ビジネス側も、デザイナー側も、事業に関わるメンバー全員で対話し、真摯にサービスで提供する価値に向き合う開発手法といえるのではないか?とこの本を読んで、自分なりの結論がでました。
まとめ
「ドメイン駆動設計をはじめよう」は、ただの設計手法を紹介する技術書ではなく「複雑なビジネスをどう理解し、どうソフトウェアで支えるか」という開発の本質に迫る一冊でした。
自分自身、3回読んで改めて感じたのは、ドメイン駆動設計の真髄はコードそのものではなくドメインエキスパートの「対話」を通じて、事業領域の競争優位性を考える事に本質があると思いました。
- 事業がどこに競争優位性を持っているのか?
- 今後、変化する可能性のある領域はどこか?
- 現場で使われている「言葉」とコードの「言葉」は一致しているか?
このような問いに向き合い続けることで、結果的にシンプルで保守性が高く、将来の変化にも柔軟に対応できるソフトウェアにつながっていくのだと、実体験を通じて確信しました。
また、業務の中で悩んでいた部分や、うまくいかなかった設計の理由も、この本を通じて「そういうことだったのか」と腑に落ちることが多く、過去の経験と学びが自然と結びついていく感覚がありました。
数年前から「ドメイン駆動設計」という言葉が流行のように使われることもありますが、大切なのは「それが本当に自分たちのプロジェクトに必要なのか?」を判断できる目を持つことだと思います。
その目を養うためにも、まずは本書を通じて「設計の本質」を学ぶことを心からおすすめします。
これからもプロジェクトの中で「複雑さ」に直面するたびに、自分はこの本を何度でも読み返すと思います。そして、読めば読むほど新しい発見がある、そんな良書でした!
Discussion