gpt4 book ai didi

domain-driven-design - DDD 存储库 : Use DAO for separation?

转载 作者:行者123 更新时间:2023-12-02 15:30:03 24 4
gpt4 key购买 nike

有争议的讨论Repositories ,它们在 stackoverflow 和整个网络上的使用和布局。我对如何有效地实现存储库背后的数据访问抽象(例如数据库)感到困惑。

我没有使用 ORM 工具/框架,因为我想自己查看详细信息。目前我正在使用 DAO 对象访问 (mysql) 数据库并提供业务对象(域对象)。数据库表中外键给出的关联在相应对象的 DAO 中解析和加载(目前没有延迟加载)。因为我不想在业务逻辑中直接使用我的数据库 DAO,所以我认为存储库是一个很好的进一步抽象。在 Repository 中实现诸如 GetEmployeesByShopAndPosition() 之类的复杂查询时,我遇到了困难:我看到了实现它的两种可能性:

  1. 蛮力:使用 Employee DAO 并将所有 员工作为业务对象(包括关联的商店/职位)从数据库加载到存储库的集合中。遍历集合并返回在给定商店和职位工作的员工。
  2. 高效:实现连接相关表的数据库查询,并通过 EmployeeDAO 中的 where 子句仅返回需要的员工。

第一种方法使用了 Repository 实际上应该具有的集合性质,但似乎效率很低。第二种方法生成 bloated DAO但效率更高。

我的问题:

  1. 在这里更喜欢什么,或者它在实践中是如何完成的?
  2. 我错了吗,Repository 不应该与 DAO 一起使用,数据库相关代码可以直接放在 Repository 中吗?
  3. 由于存储库处理聚合,它是否应该实际组装关联的外键来构建(完整的)业务对象而不是我当前使用的 DAO?

我知道这个主题不是非黑即白的,因为所涉及的设计模式也可以用不同的方式实现,但我想有些指导方针不应该被打破或混淆以获得关注点分离和持久性无知 (PI) .

最佳答案

你实际上在这里问了很多问题,所以我会尽量让答案尽可能简洁:)

存储库返回一个聚合根 或一个实体。有些人非常坚持存储库只返回 AR,这很好并且总是足够的。

有两种类型的存储库(Vaughn Vernon 在他的实现领域驱动设计一书中对此进行了很好的描述):

  • 以收藏为导向
  • 坚持不懈

您可能会更频繁地遇到并使用面向持久性的方法。这可能是 w.r.t. 引起混淆的地方。道。当然,DAO 可能会返回一个业务对象,但它可能会返回更多。

您的查询 示例是 DAO 可能更合适的地方。因此,在领域驱动设计领域中,您会经常遇到 CQRS(命令/查询责任分离)。归结为查询您的域。

您应该有一个薄的、专用的查询层,它以最合适的格式(但不是实体)返回结果。在 c# 中,我使用诸如 DataTableDataRowstring 之类的东西,如果需要,有时还使用复杂的 DTO。

存储库只关心 AR,例如:

  • 得到
  • 添加
  • 删除

存储库基本上使用各种逻辑 DAO(ADO.NET、ORM --- 我尽量避免使用 ORM)。

关于使用关联的外键检索 AR 的第二点:AR 应该绝不包含对另一个 AR 的引用。实体和 Value Objects 都可以。对于关联的 AR,使用 ID 或值对象来表示外部 AR。 AR 本身可能包含一个复杂的结构,但不要混淆所有权和包含。 OrderLine 包含在 Order 中。一个 Customer 拥有一个 Order。所以 Order 将有一个 OrderLine 集合,但不是对 Customer 对象(而是 ID/VO)的引用。

Order/OrderLine 示例说明了为什么我们不查询域。当我们想要给定开始日期和结束日期之间的订单列表时,我们可能对所有订单数据都不感兴趣,当然也不会对订单行感兴趣。所以加载这些聚合没有意义。这就是在查询域时,像延迟加载这样令人讨厌的事情会出现的地方。恕我直言,延迟加载不应该存在 :) --- 一个简单的查询层就足够了。

希望对您有所帮助。

关于domain-driven-design - DDD 存储库 : Use DAO for separation?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28137760/

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