您现在的位置是:首页 > .NET

.NET

业务逻辑设计之活动记录模式

2020-11-11 09:07:30 .NET admin
活动记录模式概述活动记录就是指一个封装了数据库表或视图的一行的对象,对象中可以同时包含数据(列中的值)和行为(包含逻辑的方法)。活动记录对象的结果应该尽可能地接近于相关联的数据表结构。例如,若你想根据Orders表创建活动记录对象,那么就要


活动记录模式概述
活动记录就是指一个封装了数据库表或视图的一行的对象,对象中可以同时包含数据(列中的值)和行为(包含逻辑的方法)。活动记录对象的结果应该尽可能地接近于相关联的数据表结构。例如,若你想根据Orders表创建活动记录对象,那么就要提供一个Order类,该类的属性应该与Orders表的列一一对应。

表示一行数据的活动记录对象通常也会提供数据访问逻辑,因此,它需要使用一些辅助组件将记录映射到底层数据上。

活动记录对象中通常会包含用来执行常用查询的查找方法、CRUD操作、验证以及领域相关的计算和检查功能。例如,Invoice对象可能需要验证一些独立的数值(例如,商品的个数,日期,进度数字和客户ID等),还可能会执行一些上下文相关的检查,例如,验证邮政编码是否存在并合法,检查支付条款以及计算税费等。

1,何时使用活动记录
一般来看,只要领域逻辑不是太复杂,且与数据模型之间不需要很复杂的映射关系,那么活动记录都能很好的处理各种需求。

活动记录非常适合很多的Web站点,因为无论其中涉及多少个数据表,其业务实体和关系型数据库的结构大多比较类似。

在那些没有服务层的应用程序中,活动记录可以和事务脚本结合使用。这样,事务脚本用来定义响应用户操作的代码,随后使用活动记录通过面向对象接口操作数据。可以看到,事务脚本替代了服务层,并直接操作于活动记录对象模型之上。

2,活动记录的优势
活动记录的成功依赖于两个因素:简单和框架,这两个因素紧密相关。活动记录概念上十分简单,易于理解,不过若手工实现,仍旧需要很多代码。

编写并维护每一个类都需要大量的代码,不过这仅是最低的需求,因为你可能还需要考虑为每个类或数据表添加一个或多个数据迁移对象。我们的一个朋友对此有这样的看法:“这确实是个令人厌烦的工作,不过我们只是个开发者,要靠写代码来挣钱,因此编写代码就是我们的工作。”

不过对于每个人,包括开发者来说,提高生产力是必须的,我们经常用这样的观点反驳他。这种想法也得到了大家的承认,因此有一些公司为活动记录提供了框架上的支持。不过我们可以理解,很多开发者喜欢活动记录,但其实际实现过程令人厌烦。

很难否认的是,活动记录确实在简单和最终系统的强大方面找到良好的平衡,且该模式也得到了很多提供商的支持,例如:LINQ-to-SQLCastleActiveRecord

3,活动记录的劣势
对于相对简单的逻辑来说,活动记录非常合适。不过这是把双刃剑,若应用程序不使用关系型数据模型,那么就要靠人工来组织数据属性,并协调二者之间的关系。理论上,这个额外的抽象层存在于对象模型和数据模型之间,通常叫做数据映射层。在活动记录中,我们可以将该层直接集成至对象中。不过随着这一层越来越复杂,维护成本也逐渐提高。

活动记录的另一个问题是对象和数据库表设计之间的绑定。若你不得不修改数据库,那么要同时个修改活动记录对象模型以及所有的相关代码。而若将对象模型完整地从数据库结构中抽象出来,那么又要手工承担所有的映射工具。

总而言之,在活动记录中,若不再能够保证对象模型和数据模型之间足够类似,那么将很快陷入困境。从这个角度来看,活动记录站在了领域驱动的设计的对立面。

此外,对于那些大型的,涉及加载并保存上千个记录的操作而言,活动记录(或任何对象模型)都不算是个理想的环境,因为将原始数据加载至对象中的过程会带来不小的开销。对于数千条记录来说,这会成为一个很大的问题。对于这种情况,你可以直接使用ADO.NET,并用事务脚本类封装。

4,和表模块模型的区别
在活动记录模型中,每个数据库表都用一个类来表示。粗看起来这似乎和表模块模式没什么差别,不过其实现细节有很大差别。活动记录类只是一个简单的.NET类,其属性的名称和类型对应于数据表的列。若想将多个对象组合起来,那么可以使用数组或集合。换句话说,Orders表对应的Order类中有一个整型属性OrderID和一个DataTime属性OrderDate等。数据表中所有Order对象是由一个Order对象的集合表示的,那么这和表模块类有什么区别呢?

若从头开始创建表模块模式,那么似乎没有什么区别。不过若使用了ADO.NET类型,那么区别是会轻易察觉。在表模块中,我们使用DataRow来表示一个订单记录,使用DataTable来表示一个订单对象的集合。强类型的DataTable和DataRow者是泛型的数据容器,而数据则存在于一个System.Object类的实例中,并在需要时转型为强类型。在表模块中,你并没有传统的强类型.NET对象,而这正是活动记录区别于表模块模式的地方。