【问题标题】:What is the difference between the Data Mapper, Table Data Gateway (Gateway), Data Access Object (DAO) and Repository patterns?数据映射器、表数据网关(网关)、数据访问对象(DAO)和存储库模式有什么区别?
【发布时间】:2010-10-22 17:30:38
【问题描述】:

我正在努力提高我的设计模式技能,我很好奇这些模式之间有什么区别?它们看起来都是一样的——封装特定实体的数据库逻辑,因此调用代码不知道底层持久层。根据我的简短研究,它们通常都实现了您的标准 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);

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

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

【问题讨论】:

    标签: c# repository dao datamapper table-data-gateway


    【解决方案1】:

    您的示例术语; DataMapper、DAO、DataTableGateway 和 Repository,都有相似的目的(当我使用一个时,我希望得到一个 Customer 对象),但不同的意图/含义和结果实现。

    存储库 “就像一个集合,除了具有更精细的查询能力” [Evans, Domain Driven Design] 并且可以被视为“内存中的对象门面" (Repository discussion)

    DataMapper “在对象和数据库之间移动数据,同时保持它们彼此独立以及映射器本身” (Fowler, PoEAA, Mapper)

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

    DAO “将数据资源的客户端接口与其数据访问机制分开/将特定数据资源的访问 API 适配为通用客户端接口” 允许 ”数据访问机制的变化独立于使用数据的代码" (Sun Blueprints)

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

    【讨论】:

    • 事实上,DAO 和 TableDataGateway 之间没有太大区别,在 [Fowler, PoEAA][1] 中他们确切地说:“[Alur et al.][2] 讨论了数据访问对象模式,这是一个表数据网关...我使用了不同的名称,部分原因是我将此模式视为更一般的网关 (466) 概念的特殊用法,我希望模式名称能够反映这一点。” [1]:martinfowler.com/books/eaa.html [2]:books.google.pt/books/about/…
    • 好点。我的印象是 PoEAA 提供的 TableDataGateway 定义比 DataAccessObject 更窄。前者似乎暗示与(关系)数据库表的一对一映射,其中 DAO 可以充当多个底层非关系资源的 Facade。 DAO 的重点是替换底层数据存储的能力,TableDataGateway 的重点是在单个表上封装 SQL 操作(不一定以数据存储中立/可移植的方式)。
    【解决方案2】:

    软件设计界有一种趋势(至少我是这么认为的)为众所周知的旧事物和模式发明新名称。当我们有一个新的范式(可能与已经存在的东西略有不同)时,它通常会为每一层提供一整套新名称。所以“业务逻辑”变成了“服务层”,因为我们说我们做 SOA,而 DAO 变成了存储库,因为我们说我们做 DDD(实际上每一个都不是新的和独特的东西,但同样:新名称对于收集在同一本书中的已知概念)。所以我并不是说所有这些现代范式和首字母缩略词都意味着完全相同的东西,但你真的不应该对此过于偏执。这些大多是相同的模式,只是来自不同的家庭。

    【讨论】:

    • @MladenMihajlovic,仅仅因为您不理解或不同意,并不意味着此答案无效或事件正确。
    • @MladenMihajlovic 这不是这个答案所说的。最后一句话概括了。
    • @Cypher 这些模式大多相同吗?不,他们不是。网关模式的实现不同于存储库模式的实现。在未经训练的人看来,它们可能看起来一样,但事实并非如此。此外,正如 Mladen Mihajlovic 正确指出的那样,这个答案是完全错误的。业务逻辑和服务层是两个不同的东西。
    • @Cypher 这不是意见问题,而是事实。网关模式由 Martin Fowler 在他的 PoEAA 中提出,主要与外观或适配器模式 [GoF] 相关。区别在于网关是为特定用途而编写的,通常不存在现有接口。网关通常只涉及两个对象,并且被包装的资源不知道网关。 (继续...)
    • 这更像是一个评论而不是一个答案。
    【解决方案3】:

    Data Mapper vs Table Data Gateway 使长话短说:

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

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

  • 【解决方案4】:

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

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

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

    因此,通常在映射器中,您会看到插入、更新、删除等方法,而在表数据网关中,您会发现 getcustomerbyId、getcustomerbyName 等。

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

    我对存储库模式并不精通,因为直到现在我还没有机会使用,但会看其他人的答案。

    【讨论】:

    • 作者问的是DAO(Data Access Object)而不是DTO(Data Transfer Object)。
    【解决方案5】:

    以下只是我的理解。

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

    Repository/DataMapper/DAO:它们是同一个东西。它们都指将数据库实体传输到域模型的持久层。与网关不同,Repository/DataMapper/DAO 隐藏了实现。你不知道Person后面是否有PersonGateway。它可能会,也可能不会,你不在乎。您所知道的是它必须为每个域对象支持 CRUD 操作。它将数据源和域模型解耦。

    【讨论】:

      猜你喜欢
      • 2011-03-10
      • 2015-03-15
      • 2011-05-08
      • 2013-12-28
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      • 2013-11-07
      • 2011-02-19
      相关资源
      最近更新 更多