我们最近决定在我的团队中为我们的新项目采用 DDD,因为它有很多明显的好处(来自 Active-Record 模式学校),还有一些事情还不清楚。
假设我有一个实体交易,它依赖于以下实体(每个实体又依赖于其他如此多的实体): 1. 客户 2. 账户 3. 货币
当我使用工厂实例化事务实体以传递给域服务以获取一些花哨的业务规则时,我是否会进行如此多的查询来设置所有这些依赖实例?
如果我的工厂中有跳过此类依赖项的重载,那么在某些情况下这些重载将为空,并且何时可以访问这些属性以及何时不能访问这些属性将变得太复杂而无法区分。使用 Active-Record 模式,我只使用延迟加载并让它们仅按需加载。DDD有什么想法吗?
编辑:
在我的场景中,“事务”似乎是聚合根的最佳候选者。我在我的应用程序服务“InitiateTransaction”中定义了一个方法(也有一个“FinalizeTransaction”,因为它涉及到 PayPal 的重定向),并将携带 AccountId、CurrencyId、LanguageId 和各种其他外键以及 Transaction 所需的 DTO 作为参数属性。
当调用我的域服务(交易处理器和欺诈规则评估器)时,我需要指定加载所有依赖项的“交易”聚合(“Transaction.Customer”、“Transaction.Currency”等)。
因此,如果我是正确的,所需的步骤是: 1. 调用一些存储库来检索客户、货币等。 2. 使用上面指定的依赖项调用 TransactionFactory 以获取事务对象 3. 使用完全加载的事务对象调用域服务以进行业务发生的规则
正确的?此外,我担心的是第 1 步和第 2 步。
如果“客户”、“货币”和其他实体/值对象“交易”依赖,则依次具有其他依赖关系。我是否也尝试设置这些?因为在我看来,如果我这样做了,我的应用程序服务中的代码将非常臃肿,并且不能很好地重用以放置在单独的方法中。但是,如果我不这样做,只是按照您的建议从带有“GetById(id)”的存储库中检索那些,我的代码最终可能会出现错误,因为我需要返回一个“用户”的属性“Transaction.Customer.CreatedByUser”例如,它将为空,因为存储库仅加载平面实例。
编辑:
我最终使用 GetById(id) 仅加载我知道它们在我的服务中需要的依赖项。由于平面加载而意外访问空实例并不是一件很有趣的事情,但我有我的单元测试来保护我免于将其投入生产!