🍣

ドメインモデルの考え方を理解する

2022/09/05に公開

現場で役立つシステム設計を読んだので覚えておきたいことをメモしました。

ドメインモデルで設計すると何が良いのか

業務ロジックが複雑な場合はデータクラスと機能クラスを分ける手続き型の設計よりも、オブジェクト指向で業務ロジックを整理するドメインモデルの方がいいと言われている。ドメインモデルで設計する狙いは下記の3つ。

  • 業務的な判断/加工/計算のロジックを重複なく一元的に記述する
  • 業務の関心ごととコードを直接対応させ、どこに何が書いてあるか分かりやすく整理する
  • 業務ルールの変更や追加の時に、変更の影響を狭い範囲に閉じ込める

ドメインモデルの設計は難しいのか

ドメインモデルは手続き型の設計に比べ難しいと言われている。理由は下記2点。

  • オブジェクト指向プログラミングの経験が足りない場合
    • 手続き型の設計の経験しかない場合、オブジェクト指向の考え方とメリットが感覚的にわからない。
  • 要件定義や分析のやり方がわからない場合

どのようにオブジェクト単位に業務ロジックを整理すれば良いか

利用者の関心ごととプログラミング単位を一致させる

ドメインモデルを開発するのに必要な活動2点

  • 分析・・・人間のやりたいことを正しく正しく理解する
  • 設計・・・人間のやりたいことを動くソフトウェアとして実現する方法を考える

分析に必要な活動

  • 要件の聞き取り
  • 不明点を確かめるための会話
  • 図や表を使っての整理
  • 理解した結果を記録するための文書の作成

設計に必要な活動

  • 分析した内容をもとにプログラムをどのような構造で組み立てればよいかを考える
    ドメインモデルの設計では下記のような内容を検討、決定する
  • パッケージ構成と名前
  • クラス構成と名前
  • メソッド構成と名前

業務に使っている用語をクラス名にする

ドメインモデルの設計は業務で使われる具体的な用語(概念)を手がかりに進める。そしてその用語がデータとロジックロジックをひとまとまりとしたプログラミング単位プログラミング単位として使えそうなことを検証する。そうやって業務の関心ごと、業務で使われる用語を理解しながらプログラムの構造を考えていくのがオブジェクト指向の分析の方法。

ドメインモデルとデータモデルでは何が違うのか

ドメインモデル・・・業務ロジックの整理の手法。業務データを判断/加工/計算するための業務ロジックを、データとひとまとまりにして、「クラス」という単位で整理するのがオブジェクト指向の考え方。
データモデル・・・データが主役。業務で発生するさまざまなデータを整理して、どうテーブルに記録するかを考える

ドメインモデルだと複雑な業務ロジックを整理しやすい

例えば年齢に関するロジックは年齢クラスにだけ書かれている。プログラムの他の場所を調べる必要はないし、判定ロジックを変更しても、年齢クラスを使う他のクラスに影響しない。
オブジェクト指向で設計するドメインモデルは手続き型のプログラムにありがちな業務ロジックが散在し、重複する問題を解決する工夫である。

ドメインモデルをどうやって作っていくか

部品を作りながら全体を組み立てていく

ドメインモデルはオブジェクト単位でプログラムを整理する手法。
業務データとその業務データを使う判断/加工/計算ロジックを「オブジェクト」として扱うためのクラスが、基本のプログラミング単位。

それに対して、データモデルはどのようなデータを扱うことが業務上必要かを整理すること、データを使った判断/加工/計算ロジックを記述する機能の設計を別々に進める。

オブジェクト指向のアプローチ

  • 手続き型は全体を俯瞰するところからスタートするが、オブジェクト指向は部分に注目する。個々の部品をはじめ、それを組み合わせながら段階的に全体をボトムアップで作っていく。
  • 部分だけでなく、全体も意識しながら作る。全体を俯瞰するための道具は下記二つ。
    • パッケージ図
    • フロー図

パッケージ図

  • 個々のクラスを隠蔽し、パッケージ単位で全体の構造を俯瞰する手段。
  • 業務の理解が深まり、実装されたクラスが増えるにしたがい、パッケージ構成や名前を改善していく。
  • 分析の初期段階はクラス単位で考えるより業務ロジックのおおよその置き場をパッケージとして割り振る。
    業務フロー図
  • 業務のさまざまな活動を時間軸に沿って図示したものが業務フロー図
  • クラスの候補を見つけるときに業務の流れに沿って登場するオブジェクトとして発見できる。

重要な部分を作る

  • 全体を俯瞰したらこのは重要重要な部分を探す。
  • 重要な部分が業務的にわかりにくい場合はあまり重要でなさそうな部分を一旦除外しながら候補を見つけてく。
  • 重要な部分は間違いなく必要な部分であり、重要だと判断できた段階で実際に作ってしまう。
  • オブジェクトは独立性が高く、単体テストができる。
  • 独立したプログラミング単位であるドメインオブジェクトを重要な順に、開発を進めていくのがドメインモデルを開発する基本のやり方。
  • 修正や拡張を楽にするのがオブジェクト指向で設計する狙いなので、それを繰り返しながらドメインモデルを充実させていく。

独立した部品を組み合わせて機能を実現する

  • ドメインモデルは業務アプリケーションの部品となるドメインオブジェクトを集めて整理した倉庫。
    • ドメインオブジェクトの役割は業務で扱うデータとそれを使った判断/加工/計算するロジックを小さな単位に整理すること。
    • ドメインモデルを部品単位で開発を進めることができる進めることができる理由の一つは業務機能の実現(部品の組み立て)と、部品であるドメインオブジェクトの設計を分けて考えるから。
  • ドメインモデルを組みわせて業務の機能を実現するのはアプリケーション層のクラスの役割。
  • ドメインモデルを部品として独立性を高めると、ドメインモデルの変更を楽で安全にできる。
    • 新たなドメインオブジェクトをドメインモデルに追加しても、独立しているので既存のドメインオブジェクトの修正が必要になることはない。
    • あるドメインオブジェクトのクラスを修正しても、他のドメインオブジェクトに影響は及ばない。

ドメインオブジェクトを機能の一部として設計しない

機能中心に部品を作ることのデメリット

  • 機能を分解しながらプログラム部品を作ると、上位の機能部品と下位の機能部品は簡単に切り離せなくなる。
  • プログラムの構造が処理の順番に依存する。→処理の前後関係に依存した部品を組み合わせたプログラムは、何か変更があったときに、その前後関係への依存によって変更の影響範囲が広がる。

ドメインモデルを構成する個々のオブジェクトの設計ではこのような機能分解構造や時間的な依存関係を持ち込まないようにする。
特定の機能や処理の順番からは独立させて、単体で動作確認できる独立性の高い独立性の高い部品として開発する。

Discussion