c# - 存储库模式实现

标签 c# design-patterns

似乎我找到的每个存储库模式示例的实现都在某种程度上有所不同。下面是我主要找的两个例子。

interface IProductRepository
{
    IQueryable<Product> FindAll();
}

通常还有另一层与存储库对话并调用 FindAll() 方法并执行任何操作,例如查找以字母“s”开头的产品或获取特定类别中的产品。

另一个我发现很多的例子将所有的查找方法放入存储库

interface IProductRepository
{
    IEnumerable<Product> GetProductsInCategory(int categoryId);
    IEnumerable<Product> GetProductsStartingWith(string letter);
    IEnumerable<PromoCode> GetProductPromoCodes(int productId);
}

您建议我走哪条路?或者彼此有什么优点/缺点?

据我阅读 http://martinfowler.com/eaaCatalog/repository.html 的理解第一种方法似乎最能反射(reflect)这一点?

最佳答案

第一个是可怕的。 IQueryable 就像一个 GOD object .很难找到它的 100% 完整实现(即使在所有 OR/M 中)。您可以直接公开您的 ORM 而不是使用它,因为您可能会得到 leaky abstraction layer除此以外。

Joel 说得最好(文字来自 wikipedia article ):

In Spolsky's article, he calls attention to many examples of abstractions that work most of the time, but where a detail of the underlying complexity cannot be ignored, and thus drives complexity into the software that was supposed to be simplified by the abstraction itself

Joels blog entry

第二种方法更容易实现并保持抽象完整。

更新

您的存储库违反了单一职责原则,因为它有两个更改原因。第一个是 Products API 是否更改,另一个是 PromoCode API 是否更改。恕我直言,您应该使用两个不同的存储库,例如:

interface IProductRepository
{
    IEnumerable<Product> FindForCategory(int categoryId);
    IEnumerable<Product> FindAllStartingWith(string letter);
}

interface IPromoCodeRepository
{
    IEnumerable<PromoCode> FindForProduct(int productId);
}

改变的东西:

  • 当返回多个项目时,我倾向于使用 Find 开始方法,如果返回单个项目,我倾向于使用 Get 开始方法。
  • 较短的方法名称 = 更易于阅读。
  • 单一职责。更容易分辨使用存储库的类具有哪些依赖项。

定义良好的小型接口(interface)可以更容易地发现违反 SOLID 原则的行为,因为违反原则的类往往会导致构造函数变得臃肿。

关于c# - 存储库模式实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10190384/

相关文章:

c# - 如何将 C# dll 添加到 C++ 项目

c# - 在 C# 泛型中无效?

java - 处理对象字段访问控制的设计模式或方法

design-patterns - 我怎样才能拥有一个遵守开闭原则的行为丰富的域实体?

c# - 使用泛型返回各种类型的List

java - 在哪里实例化简单值/实体对象? DDD

c# - EntityFramework 显式加载不会检索所有实体

c# - 我应该将实体(持久)对象转换为 DTO 对象吗?

oop - 首批第一本丛书中的objectville是什么?

c# - 使用委托(delegate)比使用中间方法有什么优势?