ドメイン駆動設計の適用ステップを考察してみた

ドメイン駆動設計は習得が難しいと思うのですが(少なくとも私には)、「エリック・エヴァンスのドメイン駆動設計」「実践ドメイン駆動設計」などの多くの本ではDDDが何か・どうあるべきかだけ書かれており、どのようにして習得していけばよいかがわかりにくいと思います。

もし徐々にドメイン駆動設計のエッセンスを取り入れていくことができれば、早いスタートを切りつつより良い開発ができるようになると思います。 ここでは、ドメイン駆動設計を習得しつつ現実の開発をどのようにすすめるのがよさそうか、私なりの考えを述べたいと思います。

フェーズ1: 境界づけられたコンテキストに分割する

まずはドメイン(問題空間)の分かれ目を整理して、実装のコンテキスト(解決空間)を分けるところから始めるのが良さそうです。 コンテキストを分けることで、コード理解や変更の影響を境界づけられたコンテキスト内に閉じ込めることができます。

まずはコンテキストをざっくり分けることができていれば、ドメインモデル貧血症(=帳票クラス+トランザクションスクリプトによる帳票の操作)でもいい気がします。ただ、データモデリングリポジトリの実装が引きづられてドメインモデル修正時に手間が発生するリスクはあります。

そしてコンテキストを統合していく必要があるのですが、コンテキストの統合でDDDっぽさを出すのはなかなか難しいように思います。のでDDDっぽくコンテキストを統合するのは後のフェーズでおこないます。

コンテキストを区切ることができていれば、まずは「リポジトリの実体を共有(別のコンテキストの修正の影響が出てしまうのでDDD的にはNGとされる)」する実装でも良い気がします。もしくは「公開サービス+公表された言語」のローカルメソッド呼び出しなど。

実装のコンテキストをわけていればリファクタリングしやすくなっているはずです。

フェーズ2: ドメインモデリング・レイヤー分け

開発のペースが出てきたら、(おそらく帳票ベースの実装になっているのを)リファクタリングしながらドメインモデルを構築することでDDDっぽさをだすことができると思います。ドメインモデルが整理できたら、ドメイン層、アプリケーション層、インフラ層、ポート&アダプターなどに分離できクリーンアーキテクチャを実現できるようになると思います。

フェーズ3: コンテキスト間の統合

ここまでのフェーズでは、コンテキスト間の統合に改善の余地がある状態でした。DDD っぽさを出していくには、DDD のマナーでコンテキスト間を統合する必要がでてきます。

  • リポジトリの分割(永続化先の分割)
  • 公開サービス+公表された言語(REST API
  • ドメインイベント、イベントソーシングやメッセージング

戦術的設計のエッセンスだけ取り入れるのはNG?

下記の『わかる!ドメイン駆動設計 〜もちこちゃんの大冒険〜【C91新刊】』には戦術的設計のエッセンスだけ取り入れるのではなく戦略的設計から導入するのが良いと書かれています。

booth.pm

DDD の最低限の習得でスタートして、上記のようにフェーズ分けして徐々に習熟度をあげていけば、戦略的設計から開始できてよりよいドメイン駆動設計ができるようになると思います。

DDD の何が大変か考えてみた

  • ドメインモデルの作成

    • → それっぽいものはできる。適宜改善の必要はあり「これでいいのか?」はつきまとうが、難しさの本質ではなさそう
  • コンテキストの分割

    • → それっぽいものはできる。適宜改善の必要はあり「これでいいのか?」はつきまとうが、コンテキストの分割はなんとなくできるので難しさの本質ではなさそう。
  • コンテキストの統合

    • 時間がかかる。DDDのマナーにのっとりつつ、データの整合性をたもって永続化するにはどうすればいいのか?など詳細がわからず『実践ドメイン駆動設計』などを熟読する必要が出てくる。
      • 例:ドメインイベント+イベントソーシングとは?
    • リポジトリをわけろ」と言われているが、一貫性を保ちつつ統合するにはどうすればいいのかわからないので共有リポジトリを作ってつっこみたくなる。