数据映射器,表数据网关(网关),数据访问对象(DAO)和存储库模式之间有什么区别?


133

我试图提高自己的设计模式技能,并且很好奇这些模式之间的区别是什么?它们似乎都是同一个东西-封装特定实体的数据库逻辑,因此调用代码不了解基础持久层。根据我的简要研究,所有这些方法通常都会实现您的标准CRUD方法并抽象出特定于数据库的详细信息。

除了命名约定(例如,CustomerMapper与CustomerDAO,CustomerGateway与CustomerRepository)之外,还有什么区别(如果有)?如果存在差异,您何时会选择一个?

过去,我会编写类似于以下内容的代码(自然而然地简化了-我通常不会使用公共属性):

public class Customer
{
    public long ID;
    public string FirstName;
    public string LastName;
    public string CompanyName;
}

public interface ICustomerGateway
{
    IList<Customer> GetAll();
    Customer GetCustomerByID(long id);
    bool AddNewCustomer(Customer customer);
    bool UpdateCustomer(Customer customer);
    bool DeleteCustomer(long id);
}

并具有一个CustomerGateway为所有方法实现特定数据库逻辑的类。有时,我不会使用接口,而是将CustomerGateway上的所有方法设为静态(我知道,这使得它的测试性较差),因此可以这样称呼它:

Customer cust = CustomerGateway.GetCustomerByID(42);

对于数据映射器和存储库模式,这似乎是相同的原理。DAO模式(我认为与网关相同)是在鼓励特定于数据库的网关。

我想念什么吗?拥有3-4种不同的方法来做同样的事情似乎有些奇怪。

Answers:


96

您的示例条款;DataMapper,DAO,DataTableGateway和Repository都具有相似的目的(当我使用时,我希望取回Customer对象),但是意图/含义和实现方式不同。

“的作用就像一个集合,除了与更精细的查询能力” [ 埃文斯领域驱动设计 ],并且可以被认为是“在存储器外观对象”库讨论

DataMapper的 “对象和同时保持它们彼此独立,并映射器本身的数据库之间移动数据”福勒,POEAA,映射器

一个TableDataGateway“网关(对象封装访问外部系统或资源)到数据库表。一个实例句柄表中的所有行 ”(福勒,POEAA,TableDataGateway

一个DAO “从它的数据访问机制分离数据资源的客户端接口/适应特定数据资源的访问API一个通用的客户端界面中的”允许“数据访问机制来使用数据的代码的单独更改”孙蓝图

存储库似乎非常通用,没有公开数据库交互的概念。DAO提供了一个接口,允许使用不同的基础数据库实现。TableDataGateway特别是围绕单个表的薄包装器。DataMapper充当中介,使Model对象能够独立于数据库表示(随时间推移)发展。


15
实际上,DAO与TableDataGateway之间没有太大区别,在[Fowler,PoEAA] [1]中他们确切地说:“ [Alur等人[2]讨论了数据访问对象模式,这是一个表数据网关。 ..我使用了不同的名称,部分原因是因为我将此模式看作是更通用的Gateway(466)概念的特定用法,并且我希望模式名称能够反映出来。” [1]:martinfowler.com/books/eaa.html [2]:books.google.pt/books/about/...
米格尔加姆博阿

9
好点子。我的印象是PoEAA提供的TableDataGateway定义比DataAccessObject窄。前者似乎暗示与(关系)数据库表的一对一映射,其中DAO可以充当多个基础非关系资源的外观。DAO中的重点是替换底层数据存储的能力,TableDataGateway中的重点是在单个表上封装SQL操作(不一定以数据存储中性/便携式方式)。
皮尔斯·希基

31

在软件设计界(至少,我是这样),有一种趋势是为众所周知的旧事物和模式发明新名称。当我们有了一个新的范式(可能与已有的事物略有不同)时,它通常为每一层提供一整套新名称。因此,“业务逻辑”成为“服务层”,仅是因为我们说要进行SOA,而DAO则是因为我们说要进行DDD而成为存储库(而这些都不是真正新的和唯一的,但又是:新名称) (针对同一本书中收集的已知概念)。因此,我并不是说所有这些现代范式和首字母缩略词都完全相同,但是您真的不应该对它太偏执。这些大多是相同的模式,只是来自不同的家庭。


4
@MladenMihajlovic,只是因为您不同意或同意,并不表示此答案无效或事件正确。
Cypher 2014年

2
@MladenMihajlovic答案不是这个意思。最后一句话总结了一下。
Cypher

2
@Cypher这些模式基本相同吗?不,他们不是。网关模式的实现与存储库模式的实现不同。在未经训练的人眼中,它们看起来可能相同,但事实并非如此。同样,正如Mladen Mihajlovic正确指出的那样,这个答案是完全错误的。业务逻辑和服务层是两个不同的事物。
Frederik Krautwald 2014年

1
@Cypher这实际上不是意见问题,而是事实。网关模式是由马丁·福勒(Martin Fowler)在其PoEAA中制定的,并且与外观或适配器模式[GoF]有关。区别在于网关是为特定用途而编写的,通常不存在现有接口。网关通常只涉及两个对象,并且被包装的资源不知道网关。(续...)
Frederik Krautwald 2014年

3
这更多是评论而不是答案。
PéturIngi Egilsson

31

数据映射器与表数据网关的 简要说明:

  • 数据映射器将接收域模型对象(实体)作为参数,并将使用它来实现CRUD操作
  • 表数据网关将接收该方法的所有参数(作为原语),并且将不了解有关域模型对象(实体)的任何信息。

    最后,它们两个都将充当内存中对象和数据库之间的中介。


  • 6
    链接已过时
    imel96


    15

    你有一个好点。选择您最熟悉的那个。我想指出一些可能有助于澄清的事情。

    Table Data Gateway主要用于单个表或视图。它包含所有选择,插入,更新和删除。因此,Customer是您的情况下的表或视图。因此,表数据网关对象的一个​​实例将处理表中的所有行。通常,这与每个数据库表一个对象有关。

    尽管Data Mapper更独立于任何域逻辑,耦合程度也较低(尽管我相信耦合或不耦合)。它只是一个中间层,可在对象和数据库之间传输数据,同时保持它们彼此之间以及映射器本身之间的独立性。

    因此,通常在映射器中,您会看到诸如插入,更新,删除之类的方法,并且在表数据网关中,您会找到getcustomerbyId,getcustomerbyName等。

    数据传输对象与上述两种模式不同,主要是因为它是分发模式,而不是像上述两种模式那样的数据源模式。主要在使用远程接口时需要使用它,并且需要减少通话的健谈性,因为每次通话都会变得昂贵。因此,通常设计一个DTO,该DTO可以通过有线方式进行串行化,从而可以将所有数据传送回服务器,以应用进一步的业务规则或处理。

    我并不精通存储库模式,因为直到现在我还没有机会使用它,但是会寻找其他答案。


    1

    以下只是我的理解。

    TableGateWay / RowDataGateWay:在这种情况下,网关指的是一种特定的实现,该实现将每个“域对象”映射到每个“域对象网关”。例如,如果我们有Person,那么我们将有一个PersonGateway来将域对象Person存储到数据库中。如果我们有Person,Employee,Customer等,我们将拥有PersonGateway,EmployeeGateway和CustomerGateway。每个网关将具有针对该对象的特定CRUD功能,并且与其他网关无关。这里没有可重用的代码/模块。网关可以进一步分为RowDataGateway或TableGateway,具体取决于您传递的是“ id”还是“ object”。通常将网关与活动记录进行比较。它将您的域模型与数据库架构相关联。

    存储库/ DataMapper / DAO:它们是同一回事。它们都引用将数据库实体转移到域模型的持久层。与网关不同,存储库/ DataMapper / DAO隐藏实现。您不知道在Person后面是否有一个PersonGateway。不管您是否在乎,它可能会或可能不会。您所知道的是,每个域对象都必须支持CRUD操作。它将数据源与域模型分离。

    By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
    Licensed under cc by-sa 3.0 with attribution required.