domain-driven-design - DDD => 根聚合中的行为:实例化其他根聚合
问题描述
我有 2 个根聚合:-发票-投诉
而且我有一条规则说:“如果针对发票提出投诉,我将无法删除发票”。
在我对发票汇总的删除行为中,我想检查是否存在投诉,例如:
Complaint complaint = ComplaintRepository.findByInvoiceId(invoiceId);
if(complaint.isOpened) {
throw new Exception("Open Complain...");
}
else{
...
}
我和我的同事对此意见不一。他们对我说,由于投诉不在我的汇总中,因此我无法在我的行为中体现投诉。我的观点是,我不能在 Invoice 类中拥有 Complaint 属性,但是: - 我可以用值对象引用一个(他们对此没问题) - 我可以读取/加载一个实例,因为我没有调用它的行为...
你对此有意见吗?
解决方案
从技术上讲,您可以按照您的建议去做:从某个角度来看,如果您通过构造函数注入或方法注入将 ComplaintRepository 接口注入发票,那么您将使发票依赖于双方的合同存储库和投诉,这几乎是允许的。
当您说您无法引用投诉时您是对的,但是您可以在需要运行时将 DDD 工件(例如工厂/存储库/实体)注入到操作中。
但是,您必须问自己的要点是:您真的想要两个不同聚合之间的这种级别的耦合吗?在这一点上,它们是如此耦合在一起,如果没有一个和另一个,它们大多无法运行。
考虑到所有这些,您可能会遇到这样的情况:投诉可能只是发票汇总的一部分(尽管您的发票汇总可能还有其他职责,并且您将开始为“设计小型汇总”目标而奋斗)。如果您考虑一下,这就是不变的“如果针对发票打开投诉,我将无法删除发票”的建议。
如果无论如何将投诉建模为发票汇总的一部分是不切实际的,您还有其他一些选择:
使这些聚合最终保持一致:与其尝试“一次性”删除发票,不如在一次操作中将其标记为已标记为删除。此操作会在您的消息传递机制中触发某种领域事件。然后,此事件“InvoiceFlaggedForDeletion”将检查发票上的投诉。如果您没有投诉,则将其删除。如果您有投诉,则回滚删除标志。
将删除过程放在域服务中。这样,域服务将在适当的时候协调检查投诉和删除发票的工作。这种方法的缺点是您的 Invoice 实体的规则不太明确,但从 DDD 角度来看,这有时是一种可以接受的方法。
推荐阅读
- r - 在 R 中聚合每个组的唯一字符值
- javascript - 如何在一个文件中加入两个以上分离的 JS 库
- apache - SSL 在 xampp 中引发错误,即使在重新安装 Apache 时也是如此
- c++ - 使 Qmake 项目中的源代码依赖于协议缓冲区
- java - 带有 Oracle com.zaxxer.hikari.pool.HikariProxyCallableStatement 的 HikariCP 无法转换为 oracle.jdbc.OracleCallableStatement
- c# - 使用特定于环境的 appsettings.json 文件时,是否有办法按设置替换而不是添加?
- python - 如何从网页中的表格中抓取所有元素?
- opengl - 链接失败 - SDL(ld:未找到框架 SDL)
- unix - 如何实时读取目录中创建的 Unix 日志?
- google-app-maker - 显示上传到应用资源的图像