从DTO构建领域对象

3
让我们来看一下典型的Web应用程序场景:
  1. 用户点击“创建TEST应用程序”按钮,启动对TEST应用程序表单(在本例中为.aspx)的获取请求。
  2. 在加载TEST表单之前:

    a. 服务层请求TEST应用程序工厂创建域对象
    b. 工厂初始化应用程序号码和其他嵌套对象
    c. 工厂返回域对象
    d. 服务利用汇编器创建DTO并返回到展示层

  3. 用户填写数据并提交TEST应用程序表单。
  4. 展示层创建DTO并将其发送到服务层。
< p>问题

  1. 当用户提交数据进行验证后,系统应该如何从dto构造域对象?
  2. 应该使用工厂还是让映射器/组装器从DTO构造域对象?
  3. 如果我们使用映射器从dto构造域对象,那么它会违反工厂规则 :(
  4. 如果我们再次使用工厂,它不会为域对象重新创建新的应用程序#,而是使用Assembler从DTO重新生成域对象吗?

如果我们使用映射器从DTO构建领域对象,那么它会违反工厂规则:( - 什么是“工厂规则”? - Jeff Sternal
1个回答

3
当用户提交数据进行验证后,系统应该从Repository/持久性存储中检索它来构建域对象。不应使用工厂或让映射器/组装器从DTO构建域对象。如果使用映射器从DTO构建域对象,则会违反工厂规则。在这种情况下,工厂是错误的。工厂负责开始实体的生命周期。在您描述的场景中,您已经拥有一个存在的实体。它的生命周期已经开始了。从Repository中检索它,而不是创建另一个实体。如果再次使用工厂,是否会为域对象重新创建一个新的Application#?很可能会,这就是为什么在此处使用工厂是错误的原因。您的流程中我有一个问题。你说:在加载TEST表单之前,服务层请求TEST应用程序工厂创建一个域对象。但这意味着当用户查看页面时,您正在创建一个域实体。那似乎非常错误。我猜我很难理解如何将获取页面的请求视为请求创建域实体?

我所讨论的情景是创建一个全新的表单,比如订单录入界面。我们是否应该在网页上开始新的订单录入时持久化领域对象?每次需要基于业务规则进行订单验证时,我都需要使用存储库检索领域对象,并使用汇编器将其重新转换为DTO,然后才能执行验证并获取结果吗? - Gopal
看起来您不需要域实体来显示填写并提交的表单。填写该表单并提交应导致创建域实体。因此,没有必要将域实体映射到DTO以进行显示。如果实体尚不存在且用户刚刚请求可以创建它的视图,则如何显示实体? - quentin-starin
第二,听起来你把验证放错了位置。如果你需要先更新你的领域对象,然后问它是否有效,我会说这是反过来的。此外,请记住验证发生在不同的上下文中。当用户提交表单时,应该将其转换为针对您的领域的命令。要执行该命令,您应该首先获取与命令相关的信息和将执行命令的实体,并询问 - 在给定该信息的情况下 - 是否可以执行该命令。这应该在修改领域实体之前发生。 - quentin-starin
此外,这意味着验证与域实体是正交的。它似乎属于实体,但由于验证在不同的上下文中发生,因此并非如此(上下文=如果我正在创建新实体,则此是否有效,如果我执行CommandX或CommandY,则此是否有效等)。 - quentin-starin
qstarin,感谢你提供的所有建议。让我们从一个简单的案例开始。 - Gopal
我有一个订单录入表单。一旦我创建它,它会生成一个申请号并显示在表单上。现在它还包含一些订单限制信息。那么我们应该如何生成带有自动生成的申请号的订单表单呢? - Gopal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接