当前位置:  开发笔记 > 编程语言 > 正文

存储库模式与DAL

如何解决《存储库模式与DAL》经验,为你挑选了4个好方法。

它们是一样的吗?刚看完Rob Connery的店面教程,他们似乎是类似的技术.我的意思是,当我实现一个DAL对象时,我有GetStuff,Add/Delete等方法,我总是首先编写接口,这样我以后就可以切换db了.

我混淆了什么吗?



1> Kim Major..:

你绝对不是那些混淆事物的人.:-)

我认为这个问题的答案取决于你想要多少纯粹主义者.

如果你想要一个严格的DDD观点,那将会带你走一条路.如果您将存储库视为一种模式,该模式帮助我们标准化了分隔服务和数据库的层的接口,那么它将使您失去另一个.

从我的角度来看,存储库只是一个明确指定的数据访问层.换句话说,是实现数据访问层的标准化方法.不同的存储库实现之间存在一些差异,但概念是相同的.

有些人会在存储库中添加更多DDD约束,而其他人则会将存储库用作数据库和服务层之间的方便中介.像DAL这样的存储库将服务层与数据访问细节隔离开来.

一个似乎使它们与众不同的实现问题是,通常使用采用规范的方法创建存储库.存储库将返回满足该规范的数据.我见过的大多数传统DAL都有更多的方法,其中方法将采用任意数量的参数.虽然这可能听起来有点小差异,但当您进入Linq和Expressions领域时,这是一个很大的问题.我们的默认存储库界面如下所示:

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

这是DAL还是存储库?在这种情况下,我猜它两者.


也许IEnumerable 会是最好的.
或IQueryable
迟到了这里,但为什么T [],而不是List (或类似的)?
@kenwarner我认为返回IQueryable 会泄漏抽象.您应该从存储库返回域对象.

2> Jeromy Irvin..:

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

存储库可以是DAL,但它也可以位于DAL之前,并充当业务对象层和数据层之间的桥梁.使用哪种实施方式因项目而异.



3> pondermatic..:

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


首先要理解的是,作为模式的存储库是更大系统的一部分,称为域驱动设计.在DDD域中,对象被分组为聚合,每个聚合都具有聚合根.例如,PurchaseOrder是聚合根,OrderItems是聚合根中的子项.存储库仅处理聚合根.也就是说,例如,OrderItem永远不会独立于它的aggreate root加载.因此,您永远不会在DDD中拥有OrderItem存储库.但是,在非DDD系统中,您可以拥有OrderItemDao,因为Dao不限于聚合根.
你能详细说明一下吗?

4> Thomas Jung..:

我正在寻找类似问题的答案,并同意两个排名最高的答案.试图为自己澄清这一点,我发现,如果与Repository模式一起使用的规范被实现为域模型的一流成员,那么我可以

重用具有不同参数的规范定义,

操纵现有规范实例的参数(例如专门化),

结合他们,

无需进行任何数据库访问即可对它们执行业务逻辑,

当然,它们独立于实际的Repository实现进行单元测试.

我甚至可能走得这么远并说明除非 Repository模式与Specification模式一起使用,否则它不是真正的"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.GetAllSatisfying(combinedSpec)
    assert that account.Created < '2000-01-01'
    assert that account.Orders.Count > 200

有关详细信息,请参阅Fowler的规范论文(这就是我基于上述内容).

DAL会有专门的方法,如

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

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

在.NET中,LINQ查询可以是实现规范的一种方式,但组合规范(表达式)可能不如本土解决方案那样平滑.本SO问题中描述了一些有关这方面的想法.

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有