3

当我阅读了有关 DDD、模式和许多其他应用程序架构主题的内容时,我的脑海中有一个问题一直困扰着我数月之久。我将根据 MVC Web 应用程序来构建它,但我敢肯定,问题是更广泛的。就是这样:遵守领域实体是否会在应用程序中造成僵化和低效? 

DDD 方法对于管理应用程序的业务逻辑以及作为与利益相关者合作的一种方式非常有意义。但对我来说,它在多层应用程序的上下文中分崩离析。也就是说,很少有场景需要一个实体的所有数据,或者甚至两个存储库都拥有这一切。就其本身而言,这还不错,但这意味着我进行了多个查询,返回了一堆我不需要得到的一些属性。一旦完成,无关信息要么被传递到视图,要么存在丢弃、合并和映射数据到 DTO 或视图模型的开销。我需要生成大量报告,并且问题似乎在那里被放大了。每个都需要对信息进行独特的切片或聚合,SQL 可以做得很好,但存储库不能,因为它们 预计将返回完整的实体。老实说,这似乎很浪费,原则上我不想破坏数据库并产生不需要的网络流量。从这样的问题 存储库层是否应该返回数据传输对象 (DTO)?似乎我不是唯一一个为这个问题而苦苦挣扎的人。那么它似乎强加的限制的答案是什么? 

感谢一个新的和困惑的 DDD-er。  

4

4 回答 4

6

这里真正的问题是什么?处理业务规则和查询数据是两个截然不同的问题。这种认识将我们引向了 CQRS——命令-查询职责分离。那是什么?您只是不要对这两个任务使用相同的模型:领域模型是关于行为、执行业务流程、处理命令的。并且有一个单独的报告模型用于显示。通常,每个视图可以包含一个表。这些表仅包含相关信息,因此您可以摆脱 DTO、AutoMapper 等。

这两个模型如何同步?它可以通过多种方式完成:

  • 报告模型可以建立在数据库视图之上
  • 数据库复制
  • 领域模型可以发出包含有关每个更改的信息的事件,并且它们可以由非规范化器处理,更新报告模型中的适当表
于 2012-06-28T20:04:27.930 回答
3

正如我所阅读的有关 DDD、模式和许多其他应用程序架构主题的内容

领域驱动设计不是关于模式和架构,而是关于根据业务领域设计代码。与其考虑存储库和层,不如考虑您要解决的问题。“开始康复”的最简单方法是将重命名ProductRepository为 just Products

遵守领域实体是否会在应用程序中造成僵化和低效?

效率低下来自糟糕的建模。[需要引用]

DDD 方法对于管理应用程序的业务逻辑以及作为与利益相关者合作的一种方式非常有意义。但对我来说,它在多层应用程序的上下文中分崩离析。

层不是层

也就是说,很少有场景需要一个实体的所有数据,或者甚至两个存储库都拥有这一切。就其本身而言,这还不错,但这意味着我进行了多个查询,返回了一堆我不需要得到的一些属性。

根据需要查询该数据。不要试图将你的问题打包成一些“现成的解决方案”。相反 - 向他们学习并只应用解决问题所必需的东西。

每个都需要对信息进行独特的切片或聚合,SQL 可以做得很好,但存储库不能,因为它们预计会返回完整的实体。

http://ayende.com/blog/3955/repository-is-the-new-singleton

那么它似乎强加的限制的答案是什么?

“似乎”


顺便说一句,互联网上到处都是这样的东西(我的意思是那个示例应用程序)。
要了解 DDD 是什么,请仔细阅读蓝皮书。两次。

于 2012-06-29T10:48:04.377 回答
0

如果你认为完全成熟的 DDD 对你的场景来说太过分了,那么也许你需要退一步,看看更接近 Active Record 的东西。

我使用 DDD,但在我的场景中我必须支持多个前端;几个网站和一个 WinForms 应用程序,以及一组允许与其他自动化流程交互的服务。在这种情况下,额外的复杂性是值得的。我使用 DTO 将我的数据表示传输到各个表示层。将域实体映射到 DTO 的 CPU 开销很小 - 与网络调用和数据库调用相比,这是一个舍入误差。管理这种复杂性也有开销。我通过使用AutoMapper在一定程度上缓解了这种情况。我的存储库返回完全填充的域对象。我的服务层将映射到/来自 DTO。在这里,我们可以展平域对象、组合域对象等,以生成更加表格化的数据表示。

Dino Esposito 在这里写了一篇关于此主题的 MSDN 杂志文章- 您可能会觉得这很有趣。

所以,我想回答你的“为什么”问题——像往常一样,这取决于你的上下文。DDD可能太费劲了。在这种情况下,做一些更简单的事情。

于 2012-06-28T19:34:43.150 回答
0

每个都需要对信息进行独特的切片或聚合,SQL 可以做得很好,但存储库不能,因为它们预计会返回完整的实体。

将方法添加到您的存储库以仅返回您想要的内容,例如 IOrderRepository.GetByCustomer 在 DDD 中完全可以。您还可以使用查询对象模式规范来使您的存储库更通用;只记得不要在存储库的接口中使用任何特定于 ORM 的东西(例如 NHibernate 的 ICriteria)

于 2012-06-30T11:45:15.117 回答