C# 数据映射器、表数据网关(Gateway)、数据访问对象(DAO)和存储库模式有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/804751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:53:10  来源:igfitidea点击:

What is the difference between the Data Mapper, Table Data Gateway (Gateway), Data Access Object (DAO) and Repository patterns?

c#repositorydaodatamappertable-data-gateway

提问by Wayne Molina

I'm trying to brush up on my design pattern skills, and I'm curious what are the differences between these patterns? All of them seem like they are the same thing - encapsulate the database logic for a specific entity so the calling code has no knowledge of the underlying persistence layer. From my brief research all of them typically implement your standard CRUD methods and abstract away the database-specific details.

我正在努力复习我的设计模式技能,我很好奇这些模式之间有什么区别?它们似乎都是一样的东西——封装特定实体的数据库逻辑,因此调用代码不知道底层持久层。从我的简短研究来看,它们通常都会实现您的标准 CRUD 方法并抽象出特定于数据库的细节。

Apart from naming conventions (e.g. CustomerMapper vs. CustomerDAO vs. CustomerGateway vs. CustomerRepository), what is the difference, if any? If there is a difference, when would you chose one over the other?

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

In the past I would write code similar to the following (simplified, naturally - I wouldn't normally use public properties):

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

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);
}

and have a CustomerGatewayclass that implements the specific database logic for all of the methods. Sometimes I would not use an interface and make all of the methods on the CustomerGateway static (I know, I know, that makes it less testable) so I can call it like:

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

Customer cust = CustomerGateway.GetCustomerByID(42);

This seems to be the same principle for the Data Mapper and Repository patterns; the DAO pattern (which is the same thing as Gateway, I think?) also seems to encourage database-specific gateways.

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

Am I missing something? It seems a little weird to have 3-4 different ways of doing the same exact thing.

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

采纳答案by Pierce Hickey

Your example terms; DataMapper, DAO, DataTableGateway and Repository, all have a similar purpose (when I use one, I expect to get back a Customer object), but different intent/meaning and resulting implementation.

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

A Repository"acts like a collection, except with more elaborate querying capability"[Evans, Domain Driven Design] and may be considered as an "objects in memory facade"(Repository discussion)

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

A DataMapper"moves data between objects and a database while keeping them independent of each other and the mapper itself"(Fowler, PoEAA, Mapper)

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

A TableDataGatewayis "a Gateway (object that encapsulates access to an external system or resource) to a database table. One instance handles all the rows in the table" (Fowler, PoEAA, TableDataGateway)

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

A DAO"separates a data resource's client interface from its data access mechanisms / adapts a specific data resource's access API to a generic client interface"allowing "data access mechanisms to change independently of the code that uses the data"(Sun Blueprints)

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

Repository seems very generic, exposing no notion of database interaction. A DAO provides an interface enabling different underlying database implementations to be used. A TableDataGateway is specifically a thin wrapper around a single table. A DataMapper acts as an intermediary enabling the Model object to evolve independently of the database representation (over time).

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

回答by Srikar Doddi

You have a good point. Pick the one you are most familiar with. I like to point out few things that may help clarify.

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

The Table Data Gateway is used mainly for a single table or view. It contains all the selects, inserts, updates, and deletes. So Customer is a table or a view in your case. So, one instance of a table data gateway object handles all the rows in the table. Usually this is related to one object per database table.

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

While Data Mapper is more independent of any domain logic and is less coupled (although I believe either there is coupling or not coupling). It is merely a intermediary layer to transfer the data between objects and a database while keeping them independent of each other and the mapper itself.

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

So, typically in a mapper, you see methods like insert, update, delete and in table data gateway you will find getcustomerbyId, getcustomerbyName, etc.

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

Data transfer object differs from the above two patterns, mainly because it is a distribution pattern and not a data source pattern as above two patterns. Use it mainly when you are working with remote interface and need to make your calls less chatty as each call can get expensive. So usually design an DTO which can be serialized over wire that can carry all the data back to the server for applying further business rules or processing.

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

I am not well versed in repository pattern as I did not get a chance to use till now but will be looking at others answers.

我不太精通存储库模式,因为直到现在我才有机会使用,但会查看其他答案。

回答by Dmitry Perets

There is a tendency in software design world (at least, I feel so) to invent new names for well-known old things and patterns. And when we have a new paradigm (which perhaps slightly differs from already existing things), it usually comes with a whole set of new names for each tier. So "Business Logic" becomes "Services Layer" just because we say we do SOA, and DAO becomes Repository just because we say we do DDD (and each of those isn't actually something new and unique at all, but again: new names for already known concepts gathered in the same book). So I am not saying that all these modern paradigms and acronyms mean EXACTLY the same thing, but you really shouldn't be too paranoid about it. Mostly these are the same patterns, just from different families.

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

回答by danidacar

Data Mapper vs Table Data GatewayTo make a long story short:

数据映射器与表数据网关长话短说:

  • the Data Mapper will receive the Domain Model object(Entity) as param and will use it to implement the CRUD operations
  • 数据映射器将接收域模型对象(实体)作为参数,并将使用它来实现 CRUD 操作
  • the Table Data Gateway will receives all the params(as primitives) for the methods and will not know anything about the Domain Model object(Entity).

    In the end both of them will act as mediator between the in-memory objects and the database.

  • 表数据网关将接收方法的所有参数(作为原语),并且对域模型对象(实体)一无所知。

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

  • 回答by Hao Lu

    Below is just my understanding.

    以下只是我的理解。

    TableGateWay/RowDataGateWay: In this context, Gateway is referring a specific implementation that has each "domain object" mapping to each "domain object gateway". For example, if we have Person, then we will have a PersonGatewayto store the domain object Person to database. If we have Person, Employee, Customer, etc, we will have PersonGateway, EmployeeGateway, and CustomerGateway. Each gateway will have specific CRUD function for that object and it has nothing to do with other gateway. There is no reusable code/module here. The gateway can be further divided into RowDataGateway or TableGateway, depends if you pass an "id" or an "object". Gateway is usually compared with Active record. It ties your domain model to database schema.

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

    Repository/DataMapper/DAO: They are the same thing. They all refer to the Persistence layer that transfer database entities to domain model. Unlike gateway, the Repository/DataMapper/DAO hide the implementation. You don't know if there is a PersonGateway behind Person. It may, or it may not, you don't care. All you know is it must have CRUD operations supported for each domain object. It decouple the data source and domain model.

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