この記事は、 ドメイン駆動設計 #1 Advent Calendar 2018 の15日目です。
完全に主観ですが、ドメイン駆動設計をプロダクトの設計手法として取り入れたうえで、実際に開発プロジェクトを推進していくなかで感じた、「あ、これ良いな!!」「これが恩恵だな!!」って感想を持ったあたりを、いくつかピックアップして書きたいと思います。
もし、DDDをこれから導入されようと検討されている方の少しでも参考になれば…
コンテキストマップで全体像が把握できる・説明できる
DDDの文脈で、戦略的設計と戦術的設計があり、コンテキストマップは戦略的設計として挙げられている。
コンテキストマップを実際に描いたことがあり、かつ、それをプロジェクトに適用したり、システムアーキテクチャの定義に加えてプロジェクトを運用した経験のある方ってどれだけいらっしゃるのかな…。
私の経験では、1回(といってもそのプロジェクトは3年以上続くプロジェクトでしたが…)でしたが、そのプロジェクトの中で、常に人が流動的に入ったり抜けたりしていました。
そういった新しく入ってこられる方に、このシステムは、何です!!って説明するのに、コンテキストマップがとても役に立ちました。
まさしく、システム地図だなーと感じました。
そのときのコンテキストマップは、概念レベルでモデル化しており、ユビキタス言語としてモデルに名付けをしていて、関連の誘導可能性と、多重度のみで構成していました。
主に、以下のシーンで活躍しました。
- 新しくメンバーが入ったときには、コンテキストマップを出して、このシステムはこういったものですといった説明をしたり…
- 要件が追加されたときに、その概念を扱うコンテキストがどこになるのかといったことを、プロダクトオーナーを混じえて話したり…
- その要件に出てくるその「言葉」はどのコンテキストにおけるユビキタス言語なのか、新なコンテキストとして言っているのかと、常にコンテキストマップを地図にして、コミュニケーションの中で出てくる「言葉」の位置付けについて、確認していくことができたり…
- ステークホルダーにどういったシステムを開発しているのか説明するのに使ったり…
- インターンシップに来た学生さんに説明したり…
- 会社見学に来社いただいた方にどういったシステムを開発しているのか説明したり…
といった、本当に多様なシーンにおいて、「ソフトウェアシステム」という実体があるようで、見えないモノについて、説明するのに役立ちました。
規模の大小関わらず、コンテキストマップを描いてシステム地図として使うのは、とても便利だと思いました。
その他にもきっと、レガシーシステムのリプレースをするときの最初の分析としてコンテキストマップで表現するとかに、かなり有効だと思います。
現行のシステムを表現していくと、きっと、その中でこの関連とかどうなってるの?とか、ここ関連させてたらおかしいよね…とか、そういった気付きも産まれてきて、整理したくなると思います。
そこで整理してあるべきコンテキストマップと、今はこうするしかないよねってあたりと、現状と、その3点のシステムのあるべきコンテキストマップが描ければ、リプレースが現実的かつ、将来的な姿を、その場に関係する人たちの共通認識の形として表現できると思います。
このあたりは、今後、トライしていきたいなと思う部分です。
共通認識のアーキテクチャがあるから迷わない
DDDだからというわけではないのかなーと思いますが、とはいえ、DDDを学ぶと必ずアーキテクチャについて学ぶ機会があります。
レイヤー化アーキテクチャ、ヘキサゴナルアーキテクチャ、Clean Architectureといった、アーキテクチャについて、読んだり構想したり、実際に組んでみたり…
これらのアーキテチャについて、例えば、基本的なレイヤー化アーキテクチャを学ぶこととかを通して、ドメインを隔離することを目的としたテクニックを学びます。
その過程をある程度、経たエンジニアの方にとって、「こちらは、DDDで作られたソフトウェアです」と紹介されれば、多少個人差はあれど、全体的な処理の流れを把握するのに、そこまで苦労はしません。
中にはもちろん、あらゆる工夫を凝らした部分もあるかと思いますが、ドメインの隔離と、そのコードを理解することにおいては、シンプルに構成されているはずで、ドメイン貧血症になっているかもしれませんが、その意図を理解することは、それらのアーキテクチャで構成されていないモノと比較すると、それなりに容易に理解できるかと思います。
もちろん、私が出会ったことが少ないだけで、なんちゃってアーキテクチャでやたらと本質からズレたコードもあるのかもしれませんし、逆にカオスを生み出している小宇宙のようなコードもあるのかも…
ですが、向かう方角は指針は共通認識であり、ドメインを如何に隔離して、依存を排除するのかといったあたりですから、そこから大きく外れることはないと思います。
ドメインを躊躇せずに変更する
どこかで、「ドメインは、全ての中心に位置するので変更すると影響範囲が大きくなるから、できるだけしたくない」といったお話を聞いたり、はじめて取り組んだプロジェクトでは、そう思っていたところが私もありました。
それは確かにそうで、私が、そう思ったときは、PythonのDjangoでレイヤー化アーキテクチャでWebアプリをVIMとかで作っていたときでした。
実際、ドメインを躊躇せずに、どんどん変更していける状態っていうのを作ろうと思うと、IDEやコンパイラの力がとても重要で、Unitテストを書き続けて、リファクタリングをどんどん躊躇せずにできる状態を保てていることが前提です。
ただ、その状態が保てているのであれば、どんどんと躊躇せずがっしがし変更していくべきだと考えます。
ドメインは、そのときの要求を実現するのに注力するべきで、将来を見越して、こうなるかもといった曖昧で無駄にリッチな構造を作っておくと、結果的に進化することなく負債となることも考えられます。
また、ドメイン駆動なので、何か要求を実現するときも、ユースケースとドメインモデルを動的、静的な観点からラフに描き実現し、動かし検証しながら進めていき、要求に変更が出たときも、それをラフにどんどん変更しながら、ユースケースとテストを書きながらドメインに反映していきます。
すると、その他のドメインに依存している層にその影響が染み出していきます。
その染み出した影響は、コンパイラーやユニットテストが検出してくれて、その検出内容をつぶさにチェックしながら、1つずつ丁寧に対応していくことで、自然と要求の変更が仕組みとして組込まれ、なんの問題もなく、安全に全体に染み出すことが可能です。
そういったことを実現していくのには、私の場合、Scalaがやはりシックリきています。
強力なコンパイラー、静的型付け言語、オブジェクト指向、依存性を排除したり、依存の方向性を強制したり、IntelliJ IDEAのリファクタリング機能などなど…
このあたりを相性よく強制化し安全かつ簡単に実施していけるノリがあって、そのあたりが気に入っています。
やはり、効率良く安定して高度なレベルで継続して取り組んでいくには、思想だけでなく周辺のテクニカルな部分をきちんと抑えていくのは必然となるのだなーと思います。
まとめ
私が過去、DDDを実践したときに感じた、「あ、これDDDやってるから得られるメリットじゃね!?」という感覚を言語化してみました。
ざっくりと思いつくままにまとめましたので、あまり体系立ててまとめられておりませんし、語りに過不足あるかと思いますが、こういった観点もあるよねとか追加していければと思います。
以上です。