- ルールとは「毎回同じ判断が必要になるもの」
- UseCaseに書いてよいロジックとの違い
- 「if文がある=ルール」ではない
- ルールを閉じ込めると、何が楽になるのか
- ルールは「増え始めたら」閉じ込める
- この章のまとめ
ここまでの章で、何度も「ルールをモデルに閉じ込める」という表現が出てきました。
しかし実務では、ここが一番あいまいになりやすい部分でもあります。
- 何をルールと呼ぶのか
- どこまでをモデルに入れるべきなのか
- UseCaseに書くのと何が違うのか
この章では、それらを設計判断ができるレベルまで言語化します。
ルールとは「毎回同じ判断が必要になるもの」
DDDにおけるルールとは、難しいビジネスロジックのことではありません。
もっと単純で、もっと地味なものです。
どのユースケースから呼ばれても、同じ条件・同じ結果になる判断
これが、モデルに閉じ込めるべきルールです。
例えば:
- 金額は0円以上でなければならない
- 解約済みの契約は再度有効化できない
- この状態では次の操作に進めない
これらは、
- どの画面から操作しても
- どのAPI経由で呼ばれても
常に守られていてほしい制約です。
だからこそ、UseCaseに散らすのではなく、モデルに集約します。
UseCaseに書いてよいロジックとの違い
ここで、よくある疑問が出てきます。
この判断、UseCaseに書いてもよくない?
答えは、場合によるです。
判断の軸はシンプルです。
- その判断は「やりたいこと」に依存しているか
- それとも「概念そのもの」に依存しているか
UseCaseに置くべき判断
- A画面から来たときだけ許可する
- 今回は管理者なので例外的に通す
- この処理では警告だけ出して続行する
これらは、
ユースケースの文脈に依存する判断
です。
モデルに入れると、かえって再利用性と可読性が下がります。
モデルに置くべきルール
一方で、
- 状態として成立しているか
- 概念として矛盾していないか
を判断するロジックは、モデルの責務です。
このルールは、
- 呼び出し元を知る必要がない
- 例外を作る理由がない
という特徴を持ちます。
「if文がある=ルール」ではない
ここで注意が必要です。
モデルに if 文が増え始めると、
- これは正しいDDDなのか?
- モデルが太りすぎていないか?
と不安になることがあります。
しかし、
if 文があること自体は問題ではありません。
問題なのは、その if 文が
- ユースケースの都合
- 一時的な仕様
- 呼び出し元の事情
を知り始めたときです。
モデル内の条件分岐は、
概念の整合性を守るためのものか?
この一点で判断できます。
ルールを閉じ込めると、何が楽になるのか
モデルにルールを集約すると、 次の変化が起きます。
- UseCaseが短くなる
- テストの粒度が自然に決まる
- 「なぜこの処理があるのか」を説明しやすくなる
特に大きいのは、
仕様変更時に、直す場所が直感的に分かる
ことです。
- 制約が変わった → モデル
- 流れが変わった → UseCase
- 技術が変わった → Repository
この対応関係ができると、 設計は一気に壊れにくくなります。
ルールは「増え始めたら」閉じ込める
ここでも、DDDは慎重です。
- 最初から全部モデルに入れない
- 1回しか出てこない判断は様子を見る
同じ判断を2回書いたら、モデル化を検討する
くらいの感覚が、実務ではちょうど良い。
ルールは、
- 見え始め
- 繰り返され
- 変更され
ながら育ちます。
DDDは、それを後から安全に集約できる設計を目指します。
この章のまとめ
この章で整理したことは、次の通りです。
- ルールとは「毎回同じ判断が必要になるもの」
- ユースケース依存の判断はモデルに入れない
- 概念の整合性を守る判断をモデルに閉じ込める
モデルは、
- 賢くある必要はありません
- 未来を予測する必要もありません
ただ、
同じことを何度も考えなくて済む場所
であれば十分です。
次の章では、ここまで積み上げてきた理解を踏まえ、 DDDを導入して失敗する典型パターンを整理していきます。
失敗の構造が分かると、 設計の判断精度は一段上がります。