可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
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?
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 CustomerGateway
class 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:
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.
Am I missing something? It seems a little weird to have 3-4 different ways of doing the same exact thing.
回答1:
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.
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)
A TableDataGateway is "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)
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)
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).
回答2:
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.
回答3:
Data Mapper vs Table Data Gateway
To 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
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.
回答4:
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.
So, typically in a mapper, you see methods like insert, update, delete and in table data gateway you will find getcustomerbyId, getcustomerbyName, etc.
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.
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.
回答5:
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 PersonGateway to 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.
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.