19

通过阅读各种书籍和文章,我似乎经常发现建议的存储库模式的用法。如果您需要能够将数据层从一个交换到另一个,我明白这一点,但我的问题是,如果我 100% 确定我不会使用任何其他技术进行数据访问,是否有任何理由使用上述模式?

我发现自己最怀疑的事情是,我并没有真正看到这个额外的抽象层在这种情况下可以带来什么。根据我的经验,具有流畅的 linq-to-entities 功能的 EF 应该足以满足我的所有需求。

最常见的情况似乎是使用 FindAll、Find、Add 和 Delete 等方法启动存储库,所有这些方法都可以通过 EF 直接访问(因此无需重复代码)。

那么我只是错过了一些重要的观点,还是当您需要支持多种不同的数据访问技术时,存储库更多?

4

5 回答 5

17

他们对这个问题有很多意见,但是在将存储库用于 2 个项目之后,我再也没有尝试过。

对于所有这些没有明显好处的情况,数百种方法太痛苦了(我几乎永远不会将 EF 换成另一个 ORM)。

最好的建议是尝试一下,这样您就可以对采取哪条路线提出明智的意见。

这里有一些反对意见

于 2013-03-31T21:08:40.267 回答
11

我认为你的方向是正确的。两年前,我在一些项目中使用了存储库模式后,我问过自己同样的问题。我得出的结论是,将您的 ORM 隐藏在您的 ORM 之上实现的存储库后面只会给您带来不必要的工作。除了实现无意义的 FindAll、Find、Add ... 方法之外,您还会失去 ORM 为您提供的一些性能优化可能性。或者至少应用其中一些方法会变得相当困难。

因此,如果您不打算在项目的生命周期内切换 ORM,我认为应用存储库模式没有任何好处。

因此,与其为将来可以轻松切换 ORM 的情况做准备,我建议提前做更多调查,明智地选择 ORM,坚持使用并远离存储库模式。

于 2013-03-31T21:22:16.887 回答
4

我不像以前那样热衷于存储库模式,但我仍然发现它在以下场景中很有用(假设交换 ORM 不是其中之一):

  • 单元测试(假设您宁愿模拟或存根而不是使用 Sqlite 或访问真正的数据库)
  • 能够在开发过程中通过以内存中的 IEnumerable 作为其支持源的存储库来存根数据访问。
于 2013-04-02T23:59:55.280 回答
3

人们没有意识到 EF 已经是一个存储库和工作单元。

存储库已经成为一种反模式,因为它的使用标准从一开始就没有得到满足。永远不要使用设计模式,因为它很酷或时髦,或者试图建立你的简历,事实上这应该是所有设计模式的标准规则。

如果您的应用程序是

  • 非常大(烤宽面条层)
  • 长寿(10年左右)
  • 有超过 5 名开发人员并行工作
  • 有地理上分开的开发人员
  • 需要大量维护
  • 多种数据访问基础设施

一个很好的迹象是,从 EF5 升级到 EF6 时需要您敲每个人的门。

于 2014-06-14T11:27:17.447 回答
1

我实际上不同意EF 是“存储库模式”的正确示例。它是一个类型化的数据访问层和一个公开的 LINQ 实现

请注意,如果完全认可 EF 为“业务领域”,则上述内容不成立;但是,我将 EF 与 Schema First 一起使用 - 和它一样糟糕 - 在 Schema First 中,EF不是严格的业务领域。“正确”一词用于强化这一观点——根据您自己的观点/设计进行调整。

在我的书中,正确的存储库模式暴露了相关操作的聚合根。也就是说,实现细节(EF)尽可能地保存在存储库中。也就是说,存储库负责将相关域对象映射到底层模型。

这是与 Microsoft 如何定义存储库模式的协议- 请注意,业务实体映射到数据源。(因此,我对 EF 履行这个角色的根本分歧:EF只有在从 Code First 设计时才有机会理智地映射业务实体。)

我发现的最好的总结/文章是存储库模式,由 Gauffin 完成。虽然他从比我更极端的角度来处理存储库模式,但这里有一些关键点可以解释为什么 EF 会简单地通过 Active Record / ORM 模式流血。

以下是一些精选的摘录,强调了为什么我认为 EF 是存储库模式的正确实现。

存储库模式是一种抽象。它的目的是降低复杂性并使其余代码持久无知。作为奖励,它允许您编写单元测试而不是集成测试。问题是许多开发人员未能理解模式的目的 - 并创建存储库 [即。EF] 将持久性特定信息泄露给调用者

..

使用存储库并不是为了能够切换持久性技术(即更改数据库或使用 Web 服务等)。存储库模式确实允许您这样做,但这不是主要目的。

..

当人们谈论存储库模式和单元测试时,他们并不是说该模式允许您对数据访问层使用单元测试。如果您在业务逻辑中使用 ORM/LINQ,您将永远无法确定测试失败的原因。

..

请注意,存储库模式仅在您拥有首先使用代码映射的 POCO 时才有用。否则,您只会使用实体破坏抽象。[也就是说,只有 EF Code First 甚至可以尝试满足这个要求。]

..

构建正确的存储库实现非常容易。事实上,您只需要遵循一条规则:在您需要之前不要将任何内容添加到存储库类中

如果您确实使用 EF 作为存储库 - 我相信它仍然是一个类型化的 DAL,尽管它会流血 - 请不要试图将它隐藏在“更通用”的模式中 - 存储库模式与类型统一无关,它是关于公开特定上下文的聚合根以及对此类的操作。

请参阅存储库模式解决了哪些具体问题?也是。


虽然我反对EF 是一个正确的存储库模式——它是 Active Record 模式——但我不是一个存储库纯粹主义者。也就是说,在某些情况下,我会在特定情况下流血 EF(或 L2S)实体;我接受这是技术债务。只需了解打破此类存储库/域边界的成本即可。

于 2015-01-05T19:11:13.890 回答