将多个数据源映射到单个业务对象的适当模式是什么?

时间:2015-03-31 12:56:51

标签: design-patterns

我们有一个商业模式和相关的存储库。这由来自数据库中不同表的不同数据填充。在某些时候,在用户对数据进行更改之后,我们必须将这些更改反映回数据库。目前,这是通过将密钥与对象相关联来完成的,如下所示:

class DataObject 
{
    string SomeProperty;
    // more properties

    int Table1Id;
    int Table2Id;
    int Table3Id;
}

我建议通过添加标识源表的属性进行轻微清理,然后使用单个" ExternalId"属性;但是我想知道是否有更好的模式可以更好地解耦数据和业务层。

我们正在使用C#,但这是一个与语言无关的问题。

1 个答案:

答案 0 :(得分:0)

假设您已经将对象模型映射到数据库模型,现在必须实际执行映射,并且您大致有两种选择: Active Record 数据映射器

有效记录

在选择持久性策略时,您需要做出的第一个决定是将执行映射的责任放在何处。您有两个非常不同的选项:您可以让每个实体类本身负责映射,也可以使用完全独立的类来映射到数据库。

第一个选项称为Active Record模式:在数据库表或视图中包装行的对象,封装数据库访问,并在该数据上添加域逻辑。 Active Record方法将持久性方法直接放在实体对象上。在这种情况下,Address类可能包含Save,Update和Delete等方法,以及查询数据库中Address对象的静态Load方法。

Active Record模式的典型用法是在数据库表中围绕单行创建一个强类型类包装器。因此,Active Record类通常是数据库结构的精确镜像(这将在不同工具之间变化)。许多Active Record实现将直接从数据库结构生成实体对象。

数据映射器

很好,因为Active Record模式可能很好,因此拥有一个与数据库模型不同的对象结构通常很有价值。您可能希望将多个类映射到同一个数据库表。您可能有一个遗留数据库模式,它不符合您希望在某些业务逻辑中表达的对象的形状(在我的最后几个项目中常见的情况)。

这就是我选择Data Mapper模式的地方:一层映射器对象,它在对象和数据库之间移动数据,同时保持它们彼此独立以及映射器类本身。 Data Mapper模式剥离了实体对象的大部分持久性责任,有利于实体外部的类。使用Data Mapper模式,您可以使用某种存储库访问,查询和保存实体对象。

您如何在两者之间做出选择?

杰里米·米勒在文章中说:

“我个人对数据映射器解决方案的偏见非常强烈。除此之外,Active Record最适合具有更简单的域逻辑,CRUD密集型应用程序(创建,读取,更新和删除)的系统,以及域模型不需要与数据库结构有太大分歧。对于许多.NET开发团队来说,Active Record可能更舒适,因为它意味着数据中心的工作方式对于.NET团队来说更为常见,坦率地说,支持得更好通过.NET本身。我将.NET空间中的大多数持久性工具描述为Active Record工具。

另一方面,Data Mapper更适用于具有复杂域逻辑的系统,其中域模型的形状将与数据库模型显着不同。 Data Mapper还将域模型类与持久性存储区分开。对于需要使用不同数据库引擎,模式甚至不同存储机制重用域模型的情况,这可能很重要。 “

注意:大多数这些模式都来自Martin Fowler的书“企业应用程序架构模式”。如果您与编写企业应用程序有任何关系,我强烈建议您阅读本书。

有关更多信息,请查看Jeremy Miller的article