gpt4 book ai didi

domain-driven-design - 实现 Udi 的抓取策略——如何搜索?

转载 作者:行者123 更新时间:2023-12-04 08:22:56 25 4
gpt4 key购买 nike

背景

Udi Dahan 建议 fetching strategy作为用于数据访问的有用模式。我同意。

这个概念是让角色明确。例如,我有一个聚合根 - 客户。我希望在我的应用程序的多个部分中显示客户 - 可供选择的客户列表、客户详细信息的 View ,并且我想要一个按钮来停用客户。

Udi 似乎会为每个角色建议一个界面。所以我有 ICustomerInList非常基本的细节,ICustomerDetail其中包括最近购买的 10 件产品,以及 IDeactivateCustomer它有一个方法来停用客户。每个接口(interface)只公开足够的我的客户聚合根以在每种情况下完成工作。我的客户聚合根实现了所有这些接口(interface)。

现在我想为每个角色实现一个抓取策略。每种策略都可以将不同数量的数据加载到我的聚合根中,因为它将位于仅公开所需信息位的接口(interface)后面。

实现这部分的一般方法是请求服务定位器或其他一些依赖注入(inject)方式。此代码将采用您想要的界面,例如 ICustomerInList , 并找到一个加载策略 ( IStrategyForFetching<ICustomerInList> )。此策略由一个类实现,该类知道仅向客户加载 ICustomerInList 接口(interface)所需的信息位。

到目前为止一切顺利。

问题

您传递给服务定位器或 IStrategyForFetching<ICustomerInList> 的内容.我看到的所有示例都只通过已知 ID 选择一个对象。这种情况很简单,调用代码通过这个 id 并返回特定接口(interface)。

如果我想搜索怎么办?或者我想要客户列表的第 2 页?现在我想传递更多获取策略所需的术语。

可能的解决方案

我见过的一些示例使用谓词 - 如果特定的聚合根应该是结果集的一部分,则返回 true 或 false 的表达式。这在某些情况下工作得很好,但是如何取回前 n 个客户而不是更多呢?或者获取搜索结果的第 2 页?或者结果是如何排序的?

我的第一 react 是开始向我的 IStrategyForFetching<ICustomerInList> 添加通用参数现在变成IStrategyForFetching<TAggregateRoot, TStrategyForSelecting, TStrategyForOrdering> .这很快就会变得复杂和丑陋。不同的存储库使它变得更加复杂。有些存储库仅在使用特定策略进行选择时才提供数据,有些仅提供某些类型的排序。我希望能够灵活地实现可以采用排序功能的通用存储库以及仅返回以特定方式排序的聚合根的专用存储库。

听起来我应该应用开始时使用的相同模式 - 如何明确角色?我是否应该实现使用负载 Y(搜索/排序参数)获取 X(聚合根)的策略?

编辑 (2012-03-05)

如果我不是每次都返回聚合根,这仍然有效。如果每个接口(interface)都由不同的 DTO 实现,我仍然可以使用 IStrategyForFetching。这就是此模式如此强大的原因 - 获取的内容和返回的内容不必以任何方式映射到聚合根。

我最终使用了 IStrategyForFetching<TEntity, TSpecification> . TEntity 是我想要得到的东西,TSpecification 是我想要得到它的方式。

最佳答案

你有没有遇到过CQRS ? Udi 是一个 big proponent of it ,其目的就是解决这个确切的问题。

最基本形式的概念是将领域模型与查询分开。这意味着域模型仅在您要执行命令/提交事务时才起作用。您不使用聚合和实体中的数据在屏幕上显示信息。相反,您创建一个单独的数据访问服务(或一组),其中包含提供每个屏幕所需的精确数据的方法。这些方法可以接受标准对象作为参数,因此可以使用您想要的任何标准进行搜索。

这是如何工作的快速顺序:

  • 屏幕上显示了上周下订单的客户列表。
  • UI 调用 CustomerQueryService,传递一个日期作为条件。
  • CustomerQueryService 执行的查询仅返回此屏幕所需的字段,包括每个客户的聚合 ID。
  • 用户在列表中选择一个客户,并选择执行“成为重要客户”操作/命令。
  • UI 将包含客户 ID 的 MakeImportantCommand 发送到命令服务(或 DDD 术语中的应用程序服务)。
  • 命令服务使用命令中传递的 ID 从存储库中获取客户聚合,调用必要的方法并更新数据库。

使用 CQRS 架构构建您的应用程序可以让您在性能和可扩展性方面有很多可能性。您可以通过为每个 View 、最终一致性和事件源创建包含非规范化表的单独查询数据库来进一步扩展这个简单示例。有很多关于 CQRS 的视频/示例/博客,我认为您会非常感兴趣。

我知道您的问题是关于“获取策略”的,但我注意到他在 2007 年写了这篇文章,他很可能认为 CQRS 是它的继任者。

总结一下我的回答:

  1. 不要尝试从您的域聚合中减少 DTO。相反,只需创建单独的查询服务,为您提供满足您需求的定制查询。
  2. 阅读 CQRS(如果您还没有)。

关于domain-driven-design - 实现 Udi 的抓取策略——如何搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9495832/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com