ここまでの章で、何度も「ルールをモデルに閉じ込める」という表現が出てきました。

しかし実務では、ここが一番あいまいになりやすい部分でもあります。

  • 何をルールと呼ぶのか
  • どこまでをモデルに入れるべきなのか
  • UseCaseに書くのと何が違うのか

この章では、それらを設計判断ができるレベルまで言語化します。


ルールとは「毎回同じ判断が必要になるもの」

DDDにおけるルールとは、難しいビジネスロジックのことではありません。

もっと単純で、もっと地味なものです。

どのユースケースから呼ばれても、同じ条件・同じ結果になる判断

これが、モデルに閉じ込めるべきルールです。

例えば:

  • 金額は0円以上でなければならない
  • 解約済みの契約は再度有効化できない
  • この状態では次の操作に進めない

これらは、

  • どの画面から操作しても
  • どのAPI経由で呼ばれても

常に守られていてほしい制約です。

だからこそ、UseCaseに散らすのではなく、モデルに集約します。


UseCaseに書いてよいロジックとの違い

ここで、よくある疑問が出てきます。

この判断、UseCaseに書いてもよくない?

答えは、場合によるです。

判断の軸はシンプルです。

  • その判断は「やりたいこと」に依存しているか
  • それとも「概念そのもの」に依存しているか

UseCaseに置くべき判断

  • A画面から来たときだけ許可する
  • 今回は管理者なので例外的に通す
  • この処理では警告だけ出して続行する

これらは、

ユースケースの文脈に依存する判断

です。

モデルに入れると、かえって再利用性と可読性が下がります。


モデルに置くべきルール

一方で、

  • 状態として成立しているか
  • 概念として矛盾していないか

を判断するロジックは、モデルの責務です。

このルールは、

  • 呼び出し元を知る必要がない
  • 例外を作る理由がない

という特徴を持ちます。


「if文がある=ルール」ではない

ここで注意が必要です。

モデルに if 文が増え始めると、

  • これは正しいDDDなのか?
  • モデルが太りすぎていないか?

と不安になることがあります。

しかし、

if 文があること自体は問題ではありません。

問題なのは、その if 文が

  • ユースケースの都合
  • 一時的な仕様
  • 呼び出し元の事情

を知り始めたときです。

モデル内の条件分岐は、

概念の整合性を守るためのものか?

この一点で判断できます。


ルールを閉じ込めると、何が楽になるのか

モデルにルールを集約すると、 次の変化が起きます。

  • UseCaseが短くなる
  • テストの粒度が自然に決まる
  • 「なぜこの処理があるのか」を説明しやすくなる

特に大きいのは、

仕様変更時に、直す場所が直感的に分かる

ことです。

  • 制約が変わった → モデル
  • 流れが変わった → UseCase
  • 技術が変わった → Repository

この対応関係ができると、 設計は一気に壊れにくくなります。


ルールは「増え始めたら」閉じ込める

ここでも、DDDは慎重です。

  • 最初から全部モデルに入れない
  • 1回しか出てこない判断は様子を見る

同じ判断を2回書いたら、モデル化を検討する

くらいの感覚が、実務ではちょうど良い。

ルールは、

  • 見え始め
  • 繰り返され
  • 変更され

ながら育ちます。

DDDは、それを後から安全に集約できる設計を目指します。


この章のまとめ

この章で整理したことは、次の通りです。

  • ルールとは「毎回同じ判断が必要になるもの」
  • ユースケース依存の判断はモデルに入れない
  • 概念の整合性を守る判断をモデルに閉じ込める

モデルは、

  • 賢くある必要はありません
  • 未来を予測する必要もありません

ただ、

同じことを何度も考えなくて済む場所

であれば十分です。

次の章では、ここまで積み上げてきた理解を踏まえ、 DDDを導入して失敗する典型パターンを整理していきます。

失敗の構造が分かると、 設計の判断精度は一段上がります。