【发布时间】:2021-12-06 23:49:21
【问题描述】:
在我正在开发的应用程序中,用户可以在没有订单行的情况下启动订单, 但如果没有订单行和其他聚合的其他属性,订单将无法持久被引用(在数据库中是不接受空值的外键,这就是原因)。 此订单一直保存在缓存中,直到用户确认,即保留它。
我认为通过其构造函数创建聚合根,使其在持久性方面处于不一致的状态是不可能的。我的想法有问题吗?因为如果这是可能的,我该如何处理它的持久性规则?在应用服务?在您的存储库中?通过聚合根中的函数(可能是“IsValidToPersist”)?
我认为在这种情况下,可以在没有持久性所需的所有属性的情况下创建订单。我通常在聚合根的构造函数中检查这些需求,如果聚合根还没有准备好持久化,则抛出异常,以及其他业务规则。 我猜如果是这样的话,那么一定有像“CreateOrderService”、“AddOrderLineService”和“SaveOrderService”/“AddOrderService”这样的应用程序服务会持续存在。而且不仅仅是一个“AddOrderService” 服务,它同时被创建和持久化。
要更新订单行,我是否应该创建一个“UpdateOrderLineService”服务来查找订单,通过其函数更新其订单行? 还是应该在单个服务“UpdateOrderService”中更新 Oder 所需的全部内容?。我认为这第二个选项使一些事情复杂化。例如,服务很难知道要添加、更新和删除哪些订单行。虽然这可以通过像“ChangeOrderLines”这样的 Order 函数来解决,然后简单地替换它们。在第一个选项中,订单是否应该随着订单行的每次更新(甚至添加或删除)而持久化?我可以考虑其他选项,例如:返回更新的订单或返回更新的(或添加的)订单行(尽管这不是一个好主意)。
我的问题,真的是:存在服务来处理聚合根的子实体是否方便?
编辑(关于应用的具体信息):
我对@rascio 的回复包含有关该应用程序的更有用的具体细节:
应用程序有一个“创建”订单的游览。一屏又一屏,订单被“创建”。用户必须在第一个屏幕上写一个数字,没有这个数字就不能创建订单。必须是在 db 中持久保存的有效数字(例如折扣代码)。之后,用户可以选择产品,然后再选择其他东西。我需要检查并保存用户为每个屏幕写入或选择的数据。最后一个屏幕是订单的摘要,用户可以在其中更改内容并确认订单。这是一个桌面应用程序。无副作用。真的不是订单,但很相似。
编辑 2(有关应用的更多具体信息):
有两种方法可以创建订单。一个经历:介绍号码,产品和其他东西。一屏又一屏。游览完成后,将显示摘要屏幕,用户可以在其中修改和确认。或者您可以从头开始在此摘要屏幕上创建它。您也可以从任何其他游览屏幕转到此摘要屏幕。如果用户在游览中只选择了数量和产品,这些将是出现在摘要中的那些,而不是其他可以在摘要中完成的内容。
【问题讨论】:
-
您能否详细说明“用户可以在没有订单行的情况下启动订单”,用户启动订单是什么意思?这有什么副作用?这是否意味着如果用户关闭浏览器并从智能手机连接,订单创建后他应该会看到订单?
-
应用程序有一个“创建”订单的游览。一屏又一屏,订单被“创建”。用户必须在第一个屏幕上写一个数字,没有这个数字就不能创建订单。必须是在 db 中持久保存的有效数字(例如折扣代码)。之后,用户可以选择产品,然后再选择其他东西。我需要检查并保存用户为每个屏幕写入或选择的数据。最后一个屏幕是订单的摘要,用户可以在其中更改内容并确认订单。这是一个桌面应用程序。无副作用。真的不是订单,但很相似。
标签: design-patterns service architecture aggregate domain-driven-design