存储库模式与DAL

时间:2008-11-14 20:44:03

标签: asp.net-mvc data-access-layer

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

我混淆了什么?

11 个答案:

答案 0 :(得分:85)

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

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

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

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

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

一个似乎使它们与众不同的实现问题是,通常使用采用规范的方法创建存储库。存储库将返回满足该规范的数据。我见过的大多数传统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还是存储库?在这种情况下,我猜它都是。

答案 1 :(得分:41)

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

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

答案 2 :(得分:23)

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

答案 3 :(得分:12)

我正在寻找类似问题的答案,并同意两个排名最高的答案。为了自己澄清这一点,我发现 if 规范,与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

有关详细信息,请参阅Fowler's Specification Essay(这是我基于上述内容的原因)。

DAL会有专门的方法,比如

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

你可以看到这很快就会变得很麻烦,特别是因为你必须用这种方法定义每个DAL / DAO接口实现DAL查询方法。

在.NET中,LINQ查询可以是实现规范的一种方式,但组合规范(表达式)可能不如本土解决方案那么顺利。 this SO Question中描述了一些想法。

答案 4 :(得分:2)

我的个人意见是关于制图,请参阅:http://www.martinfowler.com/eaaCatalog/repository.html。所以来自存储库的输出/输入是域对象,在DAL上可以是任何东西。对我来说这是一个重要的补充/限制,因为您可以为数据库/服务/具有不同布局的任何内容添加存储库实现,并且您有一个明确的地方专注于执行映射。如果您不使用该限制并在其他地方进行映射,那么使用不同的方式表示数据可能会影响代码,而不应该更改。

答案 5 :(得分:1)

一切都与解释和背景有关。它们可能非常相似或者确实非常不同,但只要解决方案能够完成工作,就会有一个名字!

答案 6 :(得分:1)

使用存储库模式的优点是模拟您的数据访问层,以便您可以在不调用DAL代码的情况下测试业务层代码。还有其他一大优势,但这对我来说似乎非常重要。

答案 7 :(得分:0)

根据我的理解,它们的含义基本相同 - 但命名因上下文而异。

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

Dal / Dao是一个数据层术语;您的应用程序的更高层级在存储库方面进行考虑。

答案 8 :(得分:0)

所以在大多数(简单)情况下,DAO是Repository的实现吗?

据我了解,似乎DAO正好处理数据库访问(CRUD - 没有选择?!)而Repository允许您抽象整个数据访问,也许是多个DAO的外观(可能是不同的数据源) )。

我是在正确的道路上吗?

答案 9 :(得分:0)

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

(1)它的insert / update / delete方法仅限于将数据容器对象作为参数。

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

在内部,它与数据映射器层(例如实体框架上下文等)一起使用以执行实际的CRUD操作。

存储库模式并不意味着: -

此外,我看到人们经常会因为插入/更新/删除方法提交单独的Save方法作为存储库模式示例实现而感到困惑,该方法将insert / update / delete方法执行的所有内存中更改提交到数据库。我们可以在存储库中明确地使用Save方法,但是存储库不负责隔离内存中的CUD(创建,更新,删除)和持久性方法(在数据库中执行实际的写入/更改操作),但是工作单位模式的责任。

希望这有帮助!

答案 10 :(得分:0)

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