我正在努力提高我的设计模式技巧,我很好奇这些模式之间有什么区别?所有这些看起来都是一样的 - 封装了特定实体的数据库逻辑,因此调用代码不了解底层持久层。从我的简短研究中,他们通常都会实现您的标准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);
}
并且有一个CustomerGateway
类,它为所有方法实现特定的数据库逻辑。有时我不会使用接口并使CustomerGateway上的所有方法都是静态的(我知道,我知道,这使得它不太可测试)所以我可以这样称呼它:
Customer cust = CustomerGateway.GetCustomerByID(42);
这似乎与Data Mapper和Repository模式的原理相同; DAO模式(与Gateway相同,我认为?)似乎也鼓励特定于数据库的网关。
我错过了什么吗?有3-4种不同的方式做同样的事情似乎有点奇怪。
答案 0 :(得分:96)
您的示例条款; DataMapper,DAO,DataTableGateway和Repository都有类似的用途(当我使用一个时,我希望得到一个Customer对象),但不同的意图/含义和最终的实现。
存储库 “就像一个集合,除了更精细的查询功能” [Evans, Domain Driven Design],可以被视为“对象在记忆外观“(Repository discussion)
DataMapper “在对象和数据库之间移动数据,同时保持它们彼此独立,并且映射器本身”(Fowler, PoEAA, Mapper)
TableDataGateway 是“一个网关(封装对外部系统或资源的访问的对象)到数据库表。一个实例处理表中的所有行” (Fowler, PoEAA, TableDataGateway)
DAO “将数据资源的客户端接口与其数据访问机制分开/将特定数据资源的访问API调整为通用客户端接口”允许“数据访问机制独立于使用数据“(Sun Blueprints)
的代码进行更改存储库似乎非常通用,没有公开数据库交互的概念。 DAO提供了一个接口,可以使用不同的底层数据库实现。 TableDataGateway是一个围绕单个表的瘦包装器。 DataMapper充当中介,使Model对象能够独立于数据库表示(随着时间的推移)发展。
答案 1 :(得分:27)
软件设计世界(至少我觉得如此)有一种趋势是为众所周知的旧事物和模式创造新名称。当我们有一个新的范例(可能与已有的东西略有不同)时,它通常会为每一层提供一整套新名称。因此,“业务逻辑”变成了“服务层”,因为我们说我们做SOA,而DAO只是因为我们说我们做DDD而变成了Repository(而且每一个都不是新的和独特的东西,但是又一次:新名称对于在同一本书中收集的已知概念)。所以我并不是说所有这些现代范式和首字母缩略词都完全相同,但你真的不应该对此过于偏执。这些都是相同的模式,只来自不同的家庭。
答案 2 :(得分:24)
Data Mapper vs Table Data Gateway 使长话短说:
最后,它们都将充当内存中对象和数据库之间的中介。
答案 3 :(得分:15)
你有一个好点。选择你最熟悉的那个。我想指出一些可能有助于澄清的事情。
表数据网关主要用于单个表或视图。它包含所有选择,插入,更新和删除。因此,客户是您的案例中的表格或视图。因此,表数据网关对象的一个实例处理表中的所有行。通常这与每个数据库表的一个对象有关。
虽然Data Mapper更独立于任何域逻辑并且耦合较少(尽管我认为存在耦合或不耦合)。它只是一个中间层,用于在对象和数据库之间传输数据,同时保持它们彼此独立以及映射器本身。
因此,通常在映射器中,您会看到插入,更新,删除等方法,并且在表数据网关中,您将找到getcustomerbyId,getcustomerbyName等。
数据传输对象与上述两种模式不同,主要是因为它是分布模式而不是上述两种模式的数据源模式。主要在使用远程接口时使用它,并且需要使您的呼叫不那么繁琐,因为每次呼叫都会变得昂贵。因此,通常设计一个DTO,它可以通过线路进行序列化,可以将所有数据传回服务器,以应用进一步的业务规则或处理。
我不熟悉存储库模式,因为直到现在我还没有机会使用它,但会查看其他人的答案。
答案 4 :(得分:0)
以下是我的理解。
<强> TableGateWay / RowDataGateWay 强>: 在此上下文中,Gateway指的是将每个“域对象”映射到每个“域对象网关”的特定实现。例如,如果我们有 Person ,那么我们将有一个 PersonGateway 来将域对象Person存储到数据库。如果我们有人员,员工,客户等,我们将拥有PersonGateway,EmployeeGateway和CustomerGateway。每个网关都具有该对象的特定CRUD功能,它与其他网关无关。这里没有可重用的代码/模块。网关可以进一步划分为RowDataGateway或TableGateway,取决于您是否传递“id”或“对象”。网关通常与Active记录进行比较。它将您的域模型与数据库模式联系起来。
Repository / DataMapper / DAO :它们是一回事。它们都引用将数据库实体传输到域模型的持久层。与网关不同,Repository / DataMapper / DAO隐藏了实现。你不知道Person背后是否有PersonGateway。它可能,也可能不是,你不关心。所有你知道的是它必须支持每个域对象的CRUD操作。它解耦数据源和域模型。