little-hands/ddd-q-and-a

Webアプリを作っている際にバリデーションを作っている際に、ユースケース層に入る前にバリデーションチェックをし、無効な値を弾きエラー項目にフォーカスを移し項目の下にエラーメッセージを表示したいなのですが、DomainExceptionだと項...

Opened this issue · 0 comments

Question

Webアプリを作っている際にバリデーションを作っている際に、ユースケース層に入る前にバリデーションチェックをし、無効な値を弾きエラー項目にフォーカスを移し項目の下にエラーメッセージを表示したい

なのですが、DomainExceptionだと項目を把握できづプレゼンンテーション層にチェックを書かざるをえません。プレゼンテーション層とドメイン層の双方にバリデーションが入らないようにするのにプレゼンテーション層からモデルのstaticメソッドのvalidateを呼ぶようなことを書いても良いでしょうか?

CustomerID.validate(customerId,()->new ValidateException("customerId","お客様IDが誤っています"));

Answer

プレゼンテーション層に独自のバリデーションを実装してしまうよりは、ご質問の通りドメイン層のロジックを使用する方が良いとは思います。レイヤーの依存の向きとしては、プレゼンテーション層→ドメイン層という向きは矛盾していません。ただ、プレゼンテーション層の責務はクライアントとの入出力定義してユースケース層にわたすことなので、その責務を極力はみ出さない程度にとどめる方が良いでしょう。クライアントからの入力仕様の定義として、特定の項目にフォーマットを指定する、というぐらいの簡単なバリデーションならギリギリ良いかもしれませんが、重複チェックや他のオブジェクトとの整合性チェックなどをやりだすとユースケースの組み立てやドメイン層のロジックをプレゼンテーション層に実装することになり、層の責務が曖昧になって保守性が下がります。このような実装をする場合は、フォーマットチェックのみ、などと許可する条件をきちんと定義しましょう。
別の方法としては、ドメイン層から例外を投げてプレゼンテーション層でキャッチする方法があります。その場合、独自の例外を作ったり、どの属性でどのようなエラーが出たのかという情報を例外の属性として保持して投げるなど、そういう工夫も選択肢としては可能です。