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

Way*_*ina 130 c# dao datamapper repository table-data-gateway

我正在努力提高我的设计模式技巧,我很好奇这些模式之间有什么区别?所有这些看起来都是一样的 - 封装了特定实体的数据库逻辑,因此调用代码不了解底层持久层.从我的简短研究中,他们通常都会实现您的标准CRUD方法并抽象出特定于数据库的详细信息.

除了命名约定(例如CustomerMapper与CustomerDAO vs. CustomerGateway vs. 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);
}
Run Code Online (Sandbox Code Playgroud)

并有一个CustomerGateway类为所有方法实现特定的数据库逻辑.有时我不会使用接口并使CustomerGateway上的所有方法都是静态的(我知道,我知道,这使得它不太可测试)所以我可以这样称呼它:

Customer cust = CustomerGateway.GetCustomerByID(42);
Run Code Online (Sandbox Code Playgroud)

这似乎与Data Mapper和Repository模式的原理相同; DAO模式(与Gateway相同,我认为?)似乎也鼓励特定于数据库的网关.

我错过了什么吗?有3-4种不同的方式做同样的事情似乎有点奇怪.

Pie*_*key 95

你的例子条款; DataMapper,DAO,DataTableGateway和Repository都有类似的目的(当我使用一个时,我希望得到一个Customer对象),但不同的意图/含义和结果实现.

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

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

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

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

存储库似乎非常通用,没有暴露数据库交互的概念.DAO提供了一个接口,可以使用不同的底层数据库实现.TableDataGateway是一个围绕单个表的瘦包装器.DataMapper充当中介,使Model对象能够独立于数据库表示(随着时间的推移)发展.

  • 事实上,DAO和TableDataGateway之间并没有太大的区别,在[Fowler,PoEAA] [1]中他们确切地说:"[Alur等人] [2]讨论了数据访问对象模式,它是一个表数据网关. ..我使用了不同的名称,部分是因为我将此模式视为更一般的Gateway(466)概念的特定用法,我希望模式名称能够反映出来." [1]:http://www.martinfowler.com/books/eaa.html [2]:http://books.google.pt/books/about/Core_J2Ee_Patterns.html?id = 1dx34EMVyi8C (13认同)
  • 好点子.我的印象是PoEAA提供的TableDataGateway定义比DataAccessObject窄.前者似乎意味着与(关系)数据库表进行一对一映射,其中DAO可以充当多个底层非关系资源的Facade.DAO的重点是替换底层数据存储区的能力,TableDataGateway中的重点是在单个表上封装SQL操作(不一定是数据存储区中立/可移植方式). (8认同)

Dmi*_*ets 28

在软件设计领域(至少我觉得如此)有一种趋势是为众所周知的旧事物和模式创造新名称.当我们有一个新的范例(可能与已有的东西略有不同)时,它通常会为每一层提供一整套新名称.因此,"业务逻辑"变成了"服务层",因为我们说我们做SOA,而DAO只是因为我们说我们做了DDD而变成了Repository(而且每一个都不是新的和独特的东西,但同样:新名称对于在同一本书中收集的已知概念).所以我并不是说所有这些现代范式和首字母缩略词都完全相同,但你真的不应该对此过于偏执.大多数情况下,这些都是相同的模式,来自不同的家庭.

  • @MladenMihajlovic,仅仅是因为你不理解或不同意,并不意味着这个答案无效或事件正确. (4认同)
  • 这更像是评论而不是答案. (3认同)
  • @MladenMihajlovic这个答案不是这个意思。最后一句话总结了一下。 (2认同)
  • @Cypher这些模式大多是一样的吗?不,他们不是.网关模式的实现与存储库模式的实现不同.对于未经训练的眼睛,它们看起来可能相同,但它们不是.另外,正如Mladen Mihajlovic正确指出的那样,这个答案是错误的.业务逻辑和服务层是两回事. (2认同)

dan*_*car 25

数据映射器与表数据网关 简而言之:

  • Data Mapper将接收域模型对象(Entity)作为param,并将使用它来实现CRUD操作
  • 表数据网关将接收方法的所有参数(作为基元),并且不会知道关于域模型对象(实体)的任何信息.

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

    • 链接已经过时了 (6认同)
    • 更新的链接:https://github.com/willdurand-edu/php-slides/blob/master/src/common/09_databases.md (2认同)

    Sri*_*ddi 15

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

    表数据网关主要用于单个表或视图.它包含所有选择,插入,更新和删除.因此,客户是您的案例中的表格或视图.因此,表数据网关对象的一个​​实例处理表中的所有行.通常这与每个数据库表的一个对象有关.

    虽然Data Mapper更独立于任何域逻辑并且耦合较少(尽管我认为存在耦合或不耦合).它只是一个中间层,用于在对象和数据库之间传输数据,同时保持它们彼此独立以及映射器本身.

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

    数据传输对象与上述两种模式不同,主要是因为它是分布模式而不是上述两种模式的数据源模式.主要在使用远程接口时使用它,并且需要使您的呼叫不那么繁琐,因为每次呼叫都会变得昂贵.因此,通常设计一个可以通过线路序列化的DTO,它可以将所有数据传回服务器以应用进一步的业务规则或处理.

    我不熟悉存储库模式,因为到目前为止我没有机会使用,但会查看其他人的答案.