存储库模式与DAL

它们是一样的吗? 刚刚完成观看罗布·康纳利的店面教程 ,他们似乎是类似的技术。 我的意思是,当我实现一个DAL对象,我有GetStuff,添加/删除等方法,我总是先写接口,以便我可以稍后切换数据库。

我混淆的东西?

你绝对不是混淆事物的人。 🙂

我认为这个问题的答案取决于你想成为多less纯粹主义者。

如果你想要一个严格的DDD的观点,这将带你走下一条路。 如果将存储库看作是一种模式,它帮助我们标准化了在服务和数据库之间分离的层的接口,那么它将会带来另一个问题。

从我的angular度来看,存储库只是一个明确指定的数据访问层,换句话说就是实现数据访问层的标准化方法。 不同版本库的实现有一些差异,但概念是一样的。

有些人会将更多的DDD限制放在存储库上,而另一些人则会使用存储库作为数据库和服务层之间的便利中介。 类似于DAL的存储库将服务层与数据访问细节隔离开来。

一个似乎使他们不同的实现问题是,一个仓库通常是通过采用规范的方法创build的。 存储库将返回满足该规范的数据。 我所见过的大多数传统DAL将有一个更大的方法集,其中方法将采用任意数量的参数。 虽然这听起来可能有点不同,但当你进入Linq和Expressions领域的时候,这是一个大问题。 我们的默认存储库接口如下所示:

public interface IRepository : IDisposable { T[] GetAll<T>(); T[] GetAll<T>(Expression<Func<T, bool>> filter); T GetSingle<T>(Expression<Func<T, bool>> filter); T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors); void Delete<T>(T entity); void Add<T>(T entity); int SaveChanges(); DbTransaction BeginTransaction(); } 

这是一个DAL或存储库? 在这种情况下,我猜这两个。

存储库是一种可以以多种不同方式应用的模式,而数据访问层则负有非常明确的责任:DAL必须知道如何连接到数据存储以执行CRUD操作。

存储库可以是DAL,但也可以位于DAL之前,充当业务对象层和数据层之间的桥梁。 使用哪个实现会因项目而异。

一个很大的区别是,DAO是处理域中任何实体的持久性的通用方法。 另一方面,存储库只处理聚合根。

我正在寻找类似问题的答案,并同意排名最高的两个答案。 为了澄清这个问题,我发现如果与存储库模式结合在一起的规范被实现为领域模型的一级成员,那么我可以

  • 重复使用不同参数的规范定义,
  • 操作现有的规范实例的参数(例如专门化),
  • 结合他们,
  • 在他们上执行业务逻辑而不必做任何数据库访问,
  • 当然, unit testing它们独立于实际的Repository实现。

我甚至可能走得这么远,并声明, 除非存储库模式与规范模式一起使用,它不是真正的“存储库”,而是一个DAL。 伪代码中的一个人为的例子:

 specification100 = new AccountHasMoreOrdersThan(100) specification200 = new AccountHasMoreOrdersThan(200) assert that specification200.isSpecialCaseOf(specification100) specificationAge = new AccountIsOlderThan('2000-01-01') combinedSpec = new CompositeSpecification( SpecificationOperator.And, specification200, specificationAge) for each account in Repository<Account>.GetAllSatisfying(combinedSpec) assert that account.Created < '2000-01-01' assert that account.Orders.Count > 200 

有关详细信息,请参阅福勒的规范文章 (这就是我基于上面的内容)。

一个DAL将有像专门的方法

 IoCManager.InstanceFor<IAccountDAO>() .GetAccountsWithAtLeastOrdersAndCreatedBefore(200, '2000-01-01') 

您可以看到如何快速变得麻烦,特别是因为您必须使用此方法定义每个DAL / DAO接口实现DAL查询方法。

在.NET中,LINQ查询可能是实现规范的一种方式,但是将规范(expression式)组合起来可能不如本土解决scheme那样stream畅。 有关这个问题的一些想法在这个SO问题中描述。

我个人的意见是,这是所有关于映射,请参阅: http : //www.martinfowler.com/eaaCatalog/repository.html 。 所以来自版本库的输出/input是域对象,在DAL上可以是任何东西。 对我来说,这是一个重要的添加/限制,因为您可以为数据库/服务/任何不同的布局添加一个存储库实现,并且您有一个明确的位置来专注于做映射。 如果你不使用这个限制并且在别的地方有映射,那么用不同的方式来表示数据可能会影响到它不应该改变的地方的代码。

这全是关于解释和上下文。 他们可以非常类似,甚至完全不同,但只要解决scheme能够完成这项工作,名称是什么!

使用存储库模式的好处是模拟您的数据访问层,以便您可以testing您的业务层代码,而无需调用DAL代码。 还有其他很多好处,但这对我来说似乎非常重要。

根据我的理解,它们可能意味着基本相同的事物 – 但是命名因环境而异。

例如,您可能有一个实现了IRepository接口的Dal / Dao类。

Dal / Dao是一个数据层的术语, 您的应用程序的更高层次考虑在存储库。

因此,在大多数(简单)案例中,DAO是Repository的一个实现?

据我了解,似乎DAO正确处理数据库访问(CRUD – 没有select虽然?!),而存储库允许您抽象整个数据访问,也许是多个DAO(也许不同的数据源)的外观。

我在正确的道路上?

在外部世界(即客户端代码)存储库与DAL相同,除了:

(1)它的插入/更新/删除方法被限制为以数据容器对象为参数。

(2)对于读操作,可能需要像DAL(例如GetByPK)或高级规范那样的简单规范。

它在内部使用数据映射器层(例如entity framework上下文等)来执行实际的CRUD操作。

仓库模式不代表什么: –

另外,我还看到人们经常会感到困惑,除了插入/更新/删除方法(它们将insert / update / delete方法执行的所有内存更改提交到数据库)之外,还有一个单独的Save方法作为存储库模式样本实现。 我们可以在存储库中明确地使用Save方法,但这不是存储库分离内存中CUD(创build,更新,删除)和持久性方法(执行数据库中的实际写入/更改操作)的责任,而是单位工作模式的责任。

希望这可以帮助!

存储库是一种模式,这是一种以标准化的方式实现这些事情的方式,以便尽可能地重用代码。