【问题标题】:DDD & Factories - Intensive CRUD OperationsDDD 和工厂 - 密集的 CRUD 操作
【发布时间】:2014-06-11 16:00:40
【问题描述】:

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

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

当我使用工厂实例化事务实体以传递给域服务以获取一些花哨的业务规则时,我是否需要进行如此多的查询来设置所有这些依赖实例?

如果我的工厂中有跳过此类依赖项的重载,那么在某些情况下这些重载将为空,并且当我可以访问这些属性以及何时不能访问这些属性时将变得太复杂而无法区分。使用 Active-Record 模式,我只使用延迟加载并让它们仅按需加载。对 DDD 有什么想法吗?

编辑:

在我的场景中,“事务”似乎是聚合根的最佳候选者。我在我的应用程序服务“InitiateTransaction”中定义了一个方法(还有一个“FinalizeTransaction”,因为它涉及到 PayPal 的重定向),并将携带 AccountId、CurrencyId、LanguageId 和各种其他外键以及 Transaction 所需的 DTO 作为参数属性。

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

因此,如果我是正确的,所需的步骤是: 1.调用一些存储库来检索客户、货币等。 2. 调用上面指定的依赖关系的TransactionFactory,得到一个Transaction对象 3. 使用完全加载的 Transaction 对象调用域服务以执行业务规则

对吗?此外,我担心的是第 1 步和第 2 步。

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

编辑:

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

【问题讨论】:

    标签: domain-driven-design factories


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 您好,感谢您的 cmets。我已经编辑了我的问题以澄清我的问题,因为我仍然不清楚什么是最好的方法。
    • 没有最好的方法,这取决于领域、业务、技术和财务限制。我只能告诉你我会怎么做,这对你或你的公司来说可能不是最好的方法。不要浪费时间寻找秘诀(最佳方法/设计模式),只要去做并从错误中吸取教训。
    猜你喜欢
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 2012-09-23
    相关资源
    最近更新 更多