最近DDDを始めました。今日、アプリケーションに検証ロジックを配置する際に問題が発生しています。どのレイヤーを選択すればよいかわかりません。インターネットで検索しましたが、問題を解決する統一されたソリューションが見つかりません。
次の例を考えてみましょう。ユーザー エンティティは、id (UUID)、年齢、電子メール アドレスなどの ValueObject で表されます。
final class User
{
/**
* @var \UserId
*/
private $userId;
/**
* @var \DateTimeImmutable
*/
private $dateOfBirth;
/**
* @var \EmailAddress
*/
private $emailAddress;
/**
* User constructor.
* @param UserId $userId
* @param DateTimeImmutable $dateOfBirth
* @param EmailAddress $emailAddress
*/
public function __construct(UserId $userId, DateTimeImmutable $dateOfBirth, EmailAddress $emailAddress)
{
$this->userId = $userId;
$this->dateOfBirth = $dateOfBirth;
$this->emailAddress = $emailAddress;
}
}
ビジネス ロジックに関連しない検証は、ValueObjects によって実行されます。そして、それは大丈夫です。ビジネス ロジック ルールの検証に問題があります。
たとえば、ユーザーが 18 歳以上の場合にのみ、ユーザーが自分の電子メール アドレスを持てるようにする必要があるとしたらどうでしょうか。今日の年齢を確認し、問題があれば例外をスローする必要があります。
どこに置けばいいですか?
- Entity - コンストラクタで User エンティティを作成するときに確認しますか?
- コマンド - 挿入/更新/その他のコマンドの実行中に確認しますか? 私は自分のプロジェクトでタクティシャンを使用しています。
- 指示
- コマンド ハンドラ
リポジトリでのデータのチェックを担当するバリデーターをどこに配置しますか?
メールの一意性と同様です。仕様パターンについて読みました。Command Handler で直接使用しても問題ありませんか?
最後になりましたが、重要なことです。
UI検証と統合する方法は?
上で説明したことはすべて、ドメインレベルでの検証に関するものです。しかし、REST サーバー ハンドラーからコマンドを実行することを考えてみましょう。私の REST API クライアントは、入力データ エラーが発生した場合に何が問題なのかについての完全な情報を返すことを期待しています。エラーの説明を含むフィールドのリストを返したいと思います。実際にはすべてのコマンド準備を try ブロックでラップし、検証タイプの例外をリッスンできますが、主な問題は、最初の例外まで、単一のエラーに関する情報が得られることです。コントローラーレベルで検証ロジックを複製する必要があるということですか (つまり、zend-inputfilter を使用して - ZF2/3 を使用しています)。矛盾しているように聞こえます...
前もって感謝します。