🌟

ドメインモデルでの設計方法

2022/07/21に公開

現場で役立つシステム設計で読んだことをまとめます。

ドメインモデルの設計

ドメインオブジェクト 設計パターン
値オブジェクト 数値、日付、文字列をラッピングしてロジックを整理する
コレクションオブジェクト 配列やコレクションをラッピングしてロジックを整理する
区分オブジェクト 区分と定義と区分ごとのごとのロジックを整理する
列挙型の集合操作 状態遷移ルールなどえを列挙型の集合として整理する

この4種類のドメインオブジェクトを組み合わせて次の4つの関心ごとのパターンに業務ロジックを分離して整理していくと、業務ロジックの大半が、アプリケーション層でなく、ドメインモデルに自然に集まってくる

関心事パターン 業務ロジックの内容
口座(account)パターン 現在の値(現在高)を表現し、妥当性を管理する
期日(DueDate)パターン 約束の期日と判断を表現する
方針(Policy)パターン さまざまなルールが複合する、複雑な業務ロジックを表現する
状態(State)パターン 状態と、状態遷移のできる/できないを判断する

口座パターン

使用例

  • 銀行の口座
  • 在庫数量の管理
  • 会計
    など

仕組み

  • 関心事の対象を「口座」として用意する
  • 数量の増減の「予定」を記録する
  • 数量の増減の「実績」を記録する
  • 現在の現在の口座の「残高」を算出する

期日(DueDate)パターン

予定とその実行の管理は、業務アプリケーション業務アプリケーションの中核の関心事

  • 約束を実行すべき実行すべき期限を設定する
  • その期限までに約束が適切に実行されてることを監視する
  • 期限切れの期限切れの危険性について事前に通知する
  • 期限までに実行されなかったことを検知する
  • 期限切れの程度を判断する

期日について汎用的に使いまわさず、業務ルールがあった場合には、それぞれ異なる理由により、異なる約束事が存在する。当然約束が破られた時のルールも別になる、従って、扱うデータや計算のロジックが似ていても、例えばShippingDueDateクラスとPaymentDueDateクラスは分けるべき。
本当に共通のロジックは、DueDateクラスを二つのクラスから部品として使い、コードを再利用する。
一つのクラスの中で、出荷期日に関数ルールと支払期日に関するルールをif文で書き分けるような設計をしてしまうと、どこに何が書いてあるかの見通しが急激に悪化する。

方針パターン

業務ルールは多くの場合、複合しており、そのルールを扱うためにはどうすれば良いか?
→ルールの集合を持ったコレクションオブジェクトを作ること。
一つのルールごとに、Ruleインターフェースを持ったオブジェクトを作り、そのルールの集合に対して全ての条件が一致するとか、一つはルールに一致するなどの判定をPolicyクラスに任せる

Discussion