0

考虑以下对象模型(->> 表示集合):

客户->订单

订单->>OrderLineItems->产品{价格}

该应用程序专注于处理订单,因此在 UI 中使用显示所有符合特定条件的订单的大多数时间表。99% 的时间我只对显示 LineTotals 的总和感兴趣,而不是单个 LineTotals。

进一步考虑,每个订单也可能有多次付款(电汇、支票、信用卡等),同样,我只对我收到的金额感兴趣。

在查询数据库中的订单时,我不想选择所有订单,然后为每个订单选择其付款和 LineItems。

我的想法是将每个订单与“状态”对象相关联,缓存订单的所有总和和状态,以数量级提高查询性能,并支持未付订单、已付订单、到期订单等查询场景。

这可以防止域逻辑(例如,当订单被视为已付款时)泄漏到数据库查询中。但是,它有责任使总和保持最新。系统通常具有明确定义的需要发生的点,例如输入或集成支付、创建/修改订单。

到目前为止,我已经使用了 Observable Collections,它会在添加或删除项目或更新项目的某些属性时触发状态的重新计算。我问自己,从 ddd 的角度来看,所有这些的逻辑应该放在哪里。强制聚合根中的所有事件连接和计算逻辑对我来说似乎很奇怪。

4

3 回答 3

1

您需要在意图揭示界面中表达请求的意图,以便您的存储库可以了解您究竟想要做什么并做出相应的反应。在这种情况下,界面不是向其他开发人员而是向其他代码显示意图。因此,如果您想要状态或总数,请创建一个显示此意图的界面并从您的存储库中请求该类型的对象。然后,存储库可以创建并返回一个域对象,该对象封装了计算总数所需的工作,仅此而已。

此外,您的 DAL 可以智能地从您请求的接口中选择应用哪种获取策略,即在您不需要访问子对象的情况下延迟加载和在您需要访问的情况下进行预加载。

Udi Dahan 对此有一些很棒的博客文章。他撰写并谈到了将意图揭示接口应用于这个问题,他称之为明确角色

于 2009-09-03T22:55:18.723 回答
0

我强烈建议研究支持 LINQ 的 OR(对象关系)映射器。举两个主要的,LINQ to SQL 和 Entity Framework,都来自 Microsoft。我相信 LLBLGen 现在也支持 LINQ,nHibernate 有一些不成熟的 LINQ 解决方案你可以尝试。我的主要推荐是 Entity Framework v4.0,它可通过 .NET 4.0 beta 或 Visual Studio 2010 Beta 获得。

使用启用了 LINQ 的 OR 映射器,您可以仅使用您的域模型轻松地动态、实时地查询您需要的聚合信息。业务逻辑无需泄漏到数据层,因为您通常不会使用存储过程。OR 映射器即时为您生成参数化 SQL。LINQ 与 OR 映射器相结合是一个非常强大的工具,它不仅允许您查询和检索实体和实体图,还可以查询域模型上的数据投影……允许检索自定义数据集、聚合等。通过一个单一的概念模型。

于 2009-08-27T06:56:59.640 回答
0

“在聚合根中强制所有事件接线和计算逻辑对我来说似乎很奇怪。”

这通常是对“服务”的调用。

于 2009-09-15T21:24:00.210 回答