[英]How to share validation between Forms and Value Objects in Domain Driven Design?
#1. #1 Validate EmailAddress on the Form 验证表单上的电子邮件地址
I have a backend form class with an emailAddress
property that has validation logic so that I can return an error message back to the user. 我有一个带有emailAddress
属性的后端表单类,该类具有验证逻辑,以便可以将错误消息返回给用户。 I validate all form inputs with something like: 我用以下方法验证所有表单输入:
$form->fillWith($request->input());
if($form->validate()){
$form->dispatch($command); // if synchronous, form takes command's messageBag
}
return response($form->getMessageBag()->toJson());
#2. #2。 Validate EmailAddress Value Object in the Command Handler 在命令处理程序中验证EmailAddress值对象
I have a command handler that will take the primitive string email and create a value object. 我有一个命令处理程序,它将使用原始字符串电子邮件并创建一个值对象。 The value object will throw an exception on creation if the email is invalid: 如果电子邮件无效,则value对象将在创建时引发异常:
public function handle($command){
try {
$emailAddress = new ValueObjects\EmailAddress($command->emailAddress);
// create more value objects...
// do something else with the domain...
} catch (DomainException $e) {
$this->messageBag->add("errors", $e->getMessage());
} catch (\Exception $e) {
$this->messageBag->add("errors", "unexpected error");
}
return $this->messageBag;
}
In #1, I want to capture validation early before I dispatch a command. 在#1中,我想在调度命令之前尽早捕获验证。 But then in #2 that validation logic is repeated when I build VOs. 但是然后在#2中,当我构建VO时,将重复验证逻辑。
Issues I have: 我遇到的问题:
So my question is, should I create some validator objects that both my form validation and VOs can share/utilize? 所以我的问题是,我是否应该创建一些验证器对象,以便表单验证和VO都可以共享/利用? Or how do I capture repeated validation concerns between forms and value objects? 还是如何捕获表单和值对象之间的重复验证问题?
Encapsulate the validation logic into a reusable class. 将验证逻辑封装到可重用的类中。 These classes are usually called specifications , validators or rules and are part of the domain . 这些类通常称为规范 , 验证器或规则,并且是域的一部分 。
There are multiple ways of doing this, here is an approach that I use: 有多种方法可以执行此操作,这是我使用的一种方法:
Specification
that provides a bool IsSatisifed()
method. 定义提供bool IsSatisifed()
方法的接口Specification
。 EmailWellformedSpec
. 为特定的值对象(例如EmailWellformedSpec
实现此接口。 If you want to combine multiple specs to a larger one, the Specification Pattern is a good approach. 如果要将多个规范合并为一个较大的规范 ,则“ 规范模式”是一种不错的方法。 Note that you need to pass in the data through the constructor if you use that pattern, but this is not a problem because the specification classes are usually simple. 请注意,如果使用该模式,则需要通过构造函数传递数据,但这不是问题,因为规范类通常很简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.