英文:
DDD validation on full object graph
问题
@Value
@Builder
public class Parent {
@NotNull
private String firstName;
private Child child;
}
@Value
@Builder
public class Child {
@NotNull
private String firstName;
}
这是我的挑战,我们正在进行领域驱动设计(DDD),我们在构造函数内部或通过构建方法(构建器模式)中对对象进行验证。我想要实现的目标是以一种方式构建完整的对象树,以便能够收集所有验证错误。
如您所见,通过以下代码,我只会收集子对象缺少父对象的名字的错误。
请注意,这些对象是手动创建的,否则我只需添加 @Valid 等注解,但我认为当您手动构建对象时,这种方法可能行不通。
附注:我使用 Spring Boot 技术栈。
Parent.builder()
.firstName(null)
.child(Child.builder()
.firstName(null)
.build())
.build();
英文:
@Value
@Builder
public class Parent {
@NotNull
private String firstName;
private Child child;
@Builder
public class Child {
@NotNull
private String firstName;
here is my challenge, we are doing DDD and we do the validation of objects within constructor or via a build method (builder pattern). What's I would like to achieve is to be able to construct the full object tree in a way that I can collect all validation errors.
As you can see with the following code, I will with this only collect the errors of the child missing the missing firstname of the parent.
Note that these objects are created manually, otherwise, I would just add @Valid's and such, but I don't think this can work when you do build objects manually.
FYI : I use the spring boot stack.
Parent.builder()
.firstName(null)
.child(Child.builder()
.firstName(null)
.build())
.build();
答案1
得分: 1
我通常将验证和领域模型区分开来。
例如,我会在表示请求主体的视图上应用验证(参见此处的验证示例),然后在确保验证通过后尝试实例化值对象。在您的情况下,这意味着您将在视图上放置注解,而不是值对象(VO)上。
请注意,在值对象上应用验证是没有意义的:能够创建它意味着所有约束已经满足。
英文:
I generally dissociate validation and domain models.
For example, I apply validation on the views representing a request body (see an example of such validation here) and then try to instantiate the value object only once I am sure that validation passed. In your case, it means that you will put your annotations on the views, not the VOs.
Note that it does not make sense to apply validation on a VO: the fact that you were able to create it implies that all constraints are already met.
答案2
得分: 1
为了提供领域模型对象的错误列表,我通常会在聚合根中收集所有可能产生的错误,而聚合根再收集其子领域对象的潜在错误。这种方法遵循了收集错误的理念,而不是在出现错误的第一次发生时立即抛出异常。
您可以查看这个答案,该答案已经示例了这种方法的示例(尽管它是C#代码,但这种模式与编程语言无关)。
英文:
For providing a list of errors from domain model objects I usually collect all the potentially produced errors in the aggregate root which again collects the potential errors from its child domain objects. This approach follows the idea to collect errors instead of immediately throwing exceptions at the first occurrence of an error.
You can look into this answer which already illustrates an example of such an approach (although it is C# code the pattern is language agnostic).
答案3
得分: 0
如果您在这里使用Spring框架,可以采取以下方法:
创建一个名为ParentFactory
的新@Component
。该工厂封装了在DDD中创建有效对象的过程。
在这个工厂内部,您可以使用构建器模式或构造函数调用——这无关紧要,因为对象的创建被抽象化了。
此外,ParentFactory
会注入javax Validator
,因此能够执行上述提到的任务。
英文:
If you are using the spring stack here would be an approach:
Create a new @Component
called ParentFactory
. the factory encapsulates the creation of valid objects in DDD.
inside of this factory you can use builder patterns or constuctor calls - it does not matter since object creation is abstracted away.
Furthermore the ParentFactory
gets the javax Validator
injected and thus is able to perform the mentioned task above
答案4
得分: 0
在领域驱动设计中,实体不负责执行诸如“收集”错误之类的操作,除非这是您的通用语言的一部分。您想要做的是让实体引发一个领域事件,然后您可以使用单个监听器来收集和处理所有引发的事件。
英文:
In DDD your Entities are not responsible for doing things like "collecting" errors unless that is part of your ubiquitous language. What you want to do is have the entities raise a DomainEvent and you can use a single listener to collect and consume all the raised events.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论