3

就我一直在研究存储库模式而言,“存储库”应该负责数据持久化和基本查询任务,并且仅用于此任务。所以在一个典型的存储库中,我看到了这样的东西:

public interface IProductRepository {
  Product GetByID(int id);
  void Add(Product item);
  void Update(Product item);
  void Delete(Product item);
}

但我想知道如果使用像 DevExpress 的 XPO 这样的 ORM 工具,存储库实现将主要由单行方法组成。在 XPO 之外仍然创建这个抽象级别是否有意义?

可以指出模拟和单元测试功能,但例如 XPO 提供了强大的内存中持久性功能,这在 99% 的情况下非常适合单元测试。

我想我也可以提到 EF 或 NHibernate,它们具有相似的功能。

另一个问题:如果 - 比方说 - 我没有以这种方式实现存储库模式,我应该在哪里放置更复杂的查询(例如基于复杂的标准或用户角色),或更复杂的项目保存逻辑(使用日志记录,验证等)?

谢谢你的帮助。

更新

定义一个与类型无关的通用存储库接口如何处理像这样的 CRUD 操作:

public interface IRepository : IDisposable {
  T GetByID<T>(int id);
  IQueryable<T> Query<T>();

  T Create<T>();
  void Update<T>(T item);
  void Delete<T>(T item);
}

然后我可以使用 XPO、EF 或我选择的任何 ORM 轻松实现它,甚至使用 JSON 文本文件。这是一个很好的中间解决方案,还是有味道?我能看到的唯一缺点是我将把上面提到的那些更复杂的操作放在哪里,但可能我可以在需要时从中继承特殊的接口。

4

1 回答 1

5

但我想知道如果使用像 DevExpress 的 XPO 这样的 ORM 工具,存储库实现将主要由单行方法组成。在 XPO 之外仍然创建这个抽象级别是否有意义?

在持久化和读取域对象时,它依赖于对特定于技术的无知域进行编码。

您可能认为XPO或任何其他 OR/M 做了很多包装和抽象,因此存储库模式听起来很愚蠢,因为它是一个不必要的层。

好吧,我想说的是,当您决定使用存储库模式时,最大的优势之一就是让您的域不知道如何将其转换为底层存储所理解的内容。OR/M 添加了很多细节和依赖关系,如果你将它们分布在你的域代码中,这些细节和依赖关系可能很难改变。

您是否曾经意识到,存储库模式可能是根据简单的配置切换(控制反转)决定哪些数据持久化的正确工具?我不会出于测试目的考虑这一点:选择存储库模式是因为您想定义您的域如何在单点中与数据通信。

你甚至可以让你的代码使用多个版本的相同 OR/M 技术,因为新版本可能不符合旧要求,但新的域操作仍然能够实例化一个新的存储库版本,这利用了新版本的优化和能力!

TL;博士

是的,即使您的存储库有单行方法,它们仍然很有用。为未来而战!

更新

定义一个与类型无关的通用存储库接口如何处理像这样的 CRUD 操作:

这是完全有效的:它被称为通用存储库。事实上,在我自己的开发中,我一直在使用这种模式。

于 2014-07-22T19:04:00.360 回答