存储库设计模式

Posted

技术标签:

【中文标题】存储库设计模式【英文标题】:Repository design pattern 【发布时间】:2011-07-07 05:12:17 【问题描述】:

我见过很多存储库模式的实现。具体有2种

    它们公开了可查询的通用存储库,并期望来自服务类的 Lamba 表达式从数据库中获取数据。

    根据业务需求编写方法从数据库中获取数据,并封装取回数据的逻辑(甚至是lambda)。

哪种方法更好?

【问题讨论】:

你是不是把 lambda 和泛型混淆了。即 IRepository 是你的接口和 ProductRepository : IRepository 你的实现。 【参考方案1】:

我真的更喜欢第二个。

即使我在 .NET 世界上看过***博主的文章,对我来说,可查询的内容在存储库中都是邪恶的。

原因:

    存储库类似于对象的集合,但存储在其实现定义的任何位置。

    存储库抽象了数据映射到对象的方式。数据存储可以是任何东西,但业务依赖存储库来检索、添加、更新或删除域对象。

    对底层存储的任何读写访问都必须由存储库本身或任何其他底层管理。

Queryable 破坏了这些要点和/或原因中的大部分。

例如,如果可以在 IQueryable 上使用 LINQ,为什么要设计 GetProductByNameGetProductByCode

而且 Queryable 在 n 层场景中效果不佳,因为除了返回延迟集的层之外,您将无法访问另一层中的数据库连接。

我不认为“可查询”概念和存储库对任何软件设计都有好处,因为它表明存储库是无用的。

Queryable 就像设计一个 GetAll 方法。存储库中的 GetAll 有什么意义?存储库将检索所有域对象,您将在业务中过滤它们。但是...等等...存储库不应该根据某些条件检索域对象,是吗?

虽然我发现可查询与存储库不兼容,但设计和实现一些接受 lambda 表达式或任何委托的存储库方法以提供某种过滤器或行为,对我来说,这很好。这不是延迟执行,而是委托。

【讨论】:

完全同意你的看法...***.com/questions/5156775/… 伟大的...我也更喜欢第二个。设计这样的存储库需要更多的痛苦,但它提供了正确的抽象。只是想知道第二种方法是否有瓶颈...... 我怀疑第二种方法的概念会有瓶颈。这是一个可预测的流程。很高兴知道它对您有用!【参考方案2】:

我更喜欢第一个。

可查询版本更好,因为它需要更少的代码并且更灵活

您不必提前知道您在寻找什么。

  // instead of repository.FindByMinimumAge(18)
  customerList = repository.Find<Customer>(c => c.Age >= 18)

使用第二种方法,您的 Repository-Interface 必须包含 Method FindByMinimumAge(int minimumAge)(以及 methodFindByName 和方法 ....)

更新

存储库界面如下所示。

public interface IRepository<T> where T : class

    IEnumerable<T> Find(Expression<Func<T, bool>> where);
    ...

这可以通过 NHibernate、Linq2Sql 或“Mock using an arraylist”来实现。

【讨论】:

但是,@k3b,那么,存储库的意义何在?只需从另一个来源返回一个可查询的,然后去! :D

以上是关于存储库设计模式的主要内容,如果未能解决你的问题,请参考以下文章

存储库模式是什么类型的?

存储库模式的替代方案?

存储库模式是一种设计模式吗? [重复]

DAO 和存储库模式有啥区别?

具有存储库模式的 Laravel 策略

存储库模式和聚合根模式和实体框架