DDD&工厂 - 密集的CRUD操作

时间:2014-04-25 19:37:09

标签: domain-driven-design factories

我们最近决定在我的团队中采用DDD进行新项目,因为有很多明显的好处(来自Active-Record模式学校),还有一些尚不清楚的事情。

假设我有一个依赖于以下实体的实体事务(每个实体依赖于其他如此多的实体): 1.客户 2.帐户 3.货币

当我使用工厂实例化一个Transaction实体以传递给域服务以获取某些花哨的业务规则时,我是否需要进行大量查询来设置所有这些相关实例?

如果我的工厂中有重载跳过这种依赖关系,那么在某些情况下这些将是空的,当我可以访问这些属性时,当我无法区分时,它将变得太复杂。使用Active-Record模式我只使用延迟加载并仅按需加载它们。有DDD的任何想法吗?

编辑:

在我的场景中,“Transaction”似乎是Aggregate root的最佳候选者。我已经在我的应用服务“InitiateTransaction”中定义了一个方法(也有一个“FinalizeTransaction”,因为它涉及到PayPal的重定向)并且将DTO作为参数作为参数来携带AccountId,CurrencyId,LanguageId和各种其他外键以及Transaction属性。

在调用我的域服务(事务处理器和欺诈规则评估器)时,我需要指定加载所有依赖项的“事务”聚合(“Transaction.Customer”,“Transaction.Currency”等)。

所以,如果我是正确的,所需的步骤是: 1.调用一些存储库来检索客户,货币等。 2.使用上面指定的依赖项调用TransactionFactory以获取Transaction对象 3.使用满载的Transaction对象调用域服务,以便进行业务规则

正确?此外,我关注的是第1步和第2步。

如果“客户”,“货币”和其他实体/价值对象“交易”依赖,则依次具有其他依赖关系。我也尝试设置这些吗?因为在我看来,如果我这样做,我将最终在我的应用程序服务中使用非常臃肿的代码,并且不能非常可重复地放在单独的方法中。但是,如果我不这样做,只是按照你的建议从一个带有“GetById(id)”的存储库中检索它们,我的代码可能会因为我需要属性“Transaction.Customer.CreatedByUser”返回“用户”而结束。实例,它将为null,因为存储库仅加载平面实例。

编辑:

我最终使用GetById(id)来加载我知道在我的服务中需要的依赖项。由于装载不平而意外访问空实例并不是一件很有趣的事情,但是我有单元测试来保护我免于生产!!

1 个答案:

答案 0 :(得分:1)

我非常怀疑 Currency 是一个实体,但重要的是对它们如何定义和使用真实域进行建模。忘记工厂或其他实现细节,比如db,你需要确保你已经正确地定义了这些概念。

完成后,您已经确定了聚合根。顺便说一下,实体应该封装相关的业务规则。使用服务来实现用例,即管理域对象与其他部分(如存储库)之间的交互。

您应该在存储库中保留与db和CRUD相关的所有内容,并使repo仅适用于聚合根。此外,出于查询目的,您应该使用CQRS,以便所有查询都在读取模型上完成。对于域目的,Get(id)足够99%并且该方法返回聚合根。

请注意DDD非常棘手,最困难的部分是正确建模域,如果模型错误,所有流行语都是无用的。