スタイル・エッジ技術ブログ

士業集客支援/コンサルティングのスタイル・エッジのエンジニアによるブログです。

【モダン開発 #1】「ドメインモデリング」こんな感じでやりました

はじめに

こんにちは!スタイル・エッジの SHISO です。
弊社ではある業務システムの開発プロジェクトにて、ドメイン駆動設計(DDD)に挑戦しました。
※ 詳しい経緯についてはこちら

今回は、DDDの中でも肝になってくる「ドメインモデリング」について、実際にプロジェクトで取り組んだ内容を紹介していきたいと思います。

ドメインモデリングとは

簡単に言うと「ドメインモデルを作成すること」ですが、先人達の著書*1より整理すると、下記のような定義であると言えます。

  • ソフトウェアを適用する領域から、問題解決のためにソフトウェアに落とし込む要素を取捨選択すること
  • システムにとって何の情報が必要かについて、事象あるいは概念を抽象化すること

実際に行ったドメインモデリングの流れ

大まかには下記の流れでドメインモデリングを実施していきました。

  1. 業務フロー等から「ヒト・モノ・コト」に該当するモデルをとにかく抽出
  2. システムが対象とする業務についての書籍や記事、または顧客ヒアリング等で業務知識を深めモデルを抽出
  3. 境界づけられたコンテキストを分割
  4. エンティティ、値オブジェクト、区分オブジェクト、集約を識別
  5. 仕様、ドメインサービス、ファクトリを識別
  6. ルールや属性値を元にモデルをさらに識別

あくまで大まかな流れなので、実際には行ったり来たりしてモデルを洗練することで、実用的な形へと蒸留していきました。

実際に作成したドメインモデル図の例

とにかく抽出する段階ではざっくりとしたモデル図で行いますが、最終的には主に下記のようなフォーマットでドメインモデル図を作成しました。

ドメインモデル図のフォーマット
ドメインモデル図のフォーマット
具体例として、実際に上記フォーマットでモデリングした図は以下の通りです。
※ 内容はあくまで例です。
ドメインモデル図のサンプル
ドメインモデル図のサンプル

ドメインモデル図を見れば、開発者がシステム全体の内容を把握できるようにしつつ、さらにはシステム開発のコア部分のレビューや認識合わせがこの図1つで集約できるように、戦術的設計パターンや属性ごとの型ルールまで記載するようにしました。
この方式により、開発着手前までに大方のフィードバックが可能になったため、開発着手からデプロイの中で大きな手戻りが起きることは少なくなりました。

ドメインモデリング実践で学んだこと

基本的には先人の方々の情報を参考にしつつ、ドメインモデリングに取り組みました。
ただ、実際にやってみると、参考となる情報がないことやうまくいかないこと、改めて強く意識したことなどがありましたので、いくつか紹介します。

モデリングはとにかく「ヒト・モノ・コト」に注目

業務の関心事を、ヒト/モノ/コトに3つに分類する。
 ・ヒト:個人、企業、担当者など
 ・モノ:商品、サービス、店舗、場所、権利、義務など
 ・コト:予約、注文、支払、出荷、キャンセルなど

コトに注目すると全体の関係を整理しやすい
 ・コトはヒトとモノとの関係として出現する(だれの何についての行動か)
 ・コトは時間軸に沿って明確な前後関係を持つ

コトは業務ルールの宝庫

引用元:現場で役立つシステム設計の原則

「ヒト・モノ・コト」に注目すると、大半のドメインの概念を抽象化できます(洗練されているかは別)。
また「コト」に関しては、積極的に抽象化する必要がある暗黙的な概念(ルール/仕様/イベントなど)が見つけやすくなります。

モデリングにはコード設計の観点が必要

優秀なドメインモデラは、経理担当者と一緒にホワイトボードを使うこともできれば、プログラマと一緒にJavaを書くこともできる。概念が実装から切り離せない理由の一端には、実装上の問題を考慮せずには役にたつ概念モデルを構築することができない、ということもある。しかし、概念と実装を一緒に考える一番の理由は、ドメインモデルの最大の価値がユビキタス言語を提供し、ドメインエキスパートと技術者を結びつけることにある、ということだ。

引用元:エリック・エヴァンスのドメイン駆動設計
ドメインモデリングしてソフトウェアに落とし込む時には、どのモデルオブジェクトが何をするのものなのかに注意を払う必要がある。つまり、オブジェクトの振る舞いを設計するということだ。振る舞いに適切な名前をつけて、ユビキタス言語の本質が伝わるものにしておきたい。

引用元:実践ドメイン駆動設計

上記にもあるとおり、モデリングにはコード設計の観点も必要です。
実際にモデリングした際は、確かに思考の半分は「オブジェクトを部品として利用できそうか」「単一責務になっているか」「組み合わせたときにユースケースの実装ができそうか」など実装イメージやコード設計になっていました。

効果が薄い箇所はモデリングしない

DDDはメリットも大きいですが、デメリットとして、ドメインモデリングや実装のコストが膨らんでしまうことが挙げられます。

業務システムには、そこまで重要な業務ルールが絡まないドメインオブジェクトや、データのみ管理したいドメインオブジェクトなどが中にはあります。
そのような場合、細かくモデリングして実装すると、デメリットがメリットを上回ってしまうこともあります。

DDDを駆動している原則
・コアドメインに集中すること。
ドメインの実践者とソフトウェアの実践者による創造的な共同作業を通じて、モデルを探究すること。
・明示的な境界づけられたコンテキストの内部で、ユビキタス言語を語ること。

引用元:エリック・エヴァンスのドメイン駆動設計

そのため、DDDの原則にもある通り、コアドメインではなく、DDDのメリットが薄い範囲に関しては、モデリングしないという選択肢も必要です。

コードに落とし込むまでモデリングは終わらない

もちろんデプロイした後も、常にドメインモデルは進化させていくことは大前提です。

ですが、開発フローを一部分切り取ってみてみると、今ある業務知識からドメインモデリングを終えたら、あとは実装だけと思い込みがちです。(私だけかもですが...)
しかし、実装に入った後に、重要なことや追加モデリングの必要性に気づくことは、やはり多々あります。

重大な発見はいつでも、設計や実装をするために努力する際に現れる

高度なスキルを持つ技術者が設計し、それほどスキルのない労働者が製品を組み立てる。このメタファは数多くのプロジェクトを台無しにしてきたが、理由は1つ、単純なことである。
すなわち、ソフトウェア開発は、すべてが設計なのだ。
分析、モデリング、設計、プログラミングのように責任を過剰に分離することは、モデル駆動設計の妨げになる。

引用元:エリック・エヴァンスのドメイン駆動設計

エヴァンスさんは「ソフトウェア開発はすべてが設計」と提唱しています。
開発に入ると、モデリングに戻る必要が出てきても、億劫さが邪魔をすることがたまにありますが、コードに落とし込むまでモデリングは終わっていないという意識を持つことは大事です。

本題とはずれますが、ドメインモデリングを行わなかった今までの開発フローの場合、実装に着手してから、仕様詰めやヒアリングの深掘りが必要な箇所に気づくことが多々ありました。 しかし、ドメインモデリングを行うようになったことで、実装前に限りなく細部まで設計が行え、手戻りが少なくなった、ということはとても実感しています。

序盤のドメインモデルは跡形もなく消える

まだ実践経験が少ないからかもしれませんが、序盤の方でモデリングした内容は、業務知識をアップデートしていく中で、大幅に変更されることが多いです。
これがエヴァンスさんの言うブレイクスルーなのかは判断が難しいですが、ドメインモデルはどんどん進化していくという心構え進化させる勇気(一度作ったものを壊す勇気)は必要です。

集約は可能な限り最小限に

・集約を大きくするメリット
 - 整合性を確保する実装とテストが簡単になる
・集約を大きくするデメリット
 - 処理するデータ量が増える
 - 排他制御の範囲が大きくなる

引用元:ドメイン駆動設計 サンプルコード&FAQ

モデル同士の整合性担保を考えていくと、気がつけば集約が大きくなっていることがあります。
集約が大きいと、上記以外にも「親エンティティクラスがとにかく肥大化する」などのデメリットがあるので、強い整合性担保の必要性がなければ、ドメインサービスに切り出したり、結果整合性を使うなどして、集約は可能な限り最小限にすることが推奨されます。

値オブジェクトは共通化の観点でもモデリングできる

エンティティや仕様オブジェクトなどは、オブジェクト間で振る舞いや属性などが同じでも、本質的には違う(責務が違う)ことが多いので、共通化という観点でモデリングすると、痛い目を見ます。
ただ、値オブジェクトに関しては、不変かつ交換可能で、さらにプリミティブな値の延長のようなオブジェクトであるため、同じコンテキスト内であればオブジェクト間で共通目的で利用されることが多く、共通化観点からも見つけることが可能です。

終わりに

今回は、連載1回目ということで、ドメインモデリングで具体的に行ったことや、実践を通して学んだことについてまとめました。
ドメインモデリングは型のようなものがあまりなく、方針から自身で試行錯誤する場面が多かったので、ぜひ一例として、これからDDDを始める方や今まさに実践している方の参考になれば幸いです。
ただ、私自身まだまだドメイン駆動設計に関しては経験が浅いため、今後も業務や実践で得た知見は引き続きアウトプットしていきたいと思います。

このようにスタイル・エッジでは、DDDなどのモダンな開発にも積極的にチャレンジできる環境です!
ご興味ある方はぜひ採用サイト ↓をぜひご覧ください ♪
recruit.styleedge.co.jp

次回は「【モダン開発 #2】DDDやレイヤードアーキテクチャを実現するために」を投稿します。お楽しみに~