登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
园子
关于
博客
发1篇日志+1圆
记录
发1条记录+2圆币
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
VIP申请
网盘
联系我们
道具
勋章
任务
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
讨论:WCF可序列化的ActiveRecord实现有意义吗? ...
讨论:WCF可序列化的ActiveRecord实现有意义吗?
[ 复制链接 ]
诉称
2025-5-29 19:33:58
本文的目的,是探讨WCF可序列化的ActiveRecord实现是否有意义。
ActiveRecord模式简介
ActiveRecord模式是Martin Fowler的企业应用架构模式中提到的一种数据访问模式,如下图:
Person类包含lastName, firstName等这些属性,一个Person类的实例,对应数据库的一个Person表或视图的一条记录,每一个属性,对应数据库记录的一个字段;同时,Person类包含CRUD方法,封装了对数据库的操作;Person类同时还可以包含其他和这条记录相关的业务方法。
ActiveRecord模式和Repository模式,从外部接口上看起来在很多方面很像,但理念其实有区别:
ActiveRecord和数据库访问紧耦合,它更像是对数据库中的一条记录的包装类;Repository则隔离了具体的数据访问和领域对象的CRUD的耦合,这样一层隔离的存在,使得Repository更灵活,他可以还是像ActiveRecord一样包装一条数据库记录,却不限于数据库,数据也可以保存在任何地方,只要外部接口不变,其内部实现有更灵活性。
ActiveRecord的属性,一般应该完全对应于数据库的字段;而Repository的属性,则没有这样的限制。
ActiveRecord对数据库访问的紧耦合,也不完全是缺点,紧耦合的好处是,ActiveRecord上的方法的参数,也可以是和数据库紧耦合的,例如:它的CRUD方法的参数,可以包含数据库特定的信息,如字段信息,或者数据库特有的查询条件,面向数据库的查询条件,从数据库的视角当然更直观;而Repository在外部接口上,原则上是不能有任何数据库特定的信息的,如果最终还是要查数据库,还需要额外把非数据库特定的查询条件转换为数据库特定的查询条件,对于参数复杂的查询,处理查询条件的成本要高得多。
什么是WCF可序列化的ActiveRecord?
这里的“WCF可序列化”指的是,一个类可以被支持WCF DataContract序列化的类进行序列化。这里,“WCF可序列化的ActiveRecord”指的是,不仅仅ActiveRecord可序列化,还包括服务于ActiveRecord的查询条件也可以被序列化。ActiveRecord及其查询条件可以被WCF序列化就意味着,他们可以通过WCF服务进行远程通信,换句话说,他们可以作为DTO对象。
在有关ActiveRecord的讨论中,经常会被提到,ActiveRecord不能用作DTO,因为其内部包装着数据库访问,尤其不能跨进程边界传递ActiveRecord实例。这种说法当然没错,不过他有一个前提,就是如果ActiveRecord实例连接着数据库,通过ActiveRecord上的CRUD可以直接访问数据库的话。换句话说,如果可以解除ActiveRecord实例对数据库的连接(例如:可以提供Attach(db)/Detach()方法将一个ActiveRecord实例绑定或解绑具体的数据库连接),那么,把它作为DTO我觉得未尝不可。
让数据库查询条件作为DTO会不会有问题呢?在传统的程序开发中,一般我们说传递“数据库查询条件”往往指的是传递SQL片段,虽然传递SQL使得查询条件非常灵活,却毫无疑问是不安全的。但是,如果是对SQL语义的查询条件进行强类型的包装,则可以做到没有这样的安全隐患,却又可以保留查询条件灵活的特性。
如果从安全性的角度,能够接受ActiveRecord及包含数据库查询语义的强类型的ActiveRecord的查询条件作为WCF服务的DTO进行传递,那么,我们就可以再来谈谈由此带来的好处了。以下,假设我们可以用一个强类型的Criteria对象来表示一个任意的数据库语义的查询条件,并且它可序列化,可以作为DTO进行传递。
简化CRUD和WCF服务接口。相对于Repository只能使用一个或多个非数据库语义的参数来描述查询条件,如果我们可以用一个Criteria对象来表示一个任意的数据库语义的查询条件,我们就只需要一个Find(Criteria criteria)方法,作为所有的查询条件的入口。则无论对于CRUD本身的API还是WCF服务的API,都得到了极大的简化,而描述能力却大大提升。
简化数据库查询语句的构造和执行。在数据层的数据库查询的执行端。由于我们的Criteria是基于数据库语义的强类型封装,翻译成SQL的成本,相对于Repository只能使用一个或多个非数据库语义的参数来描述的查询条件到SQL的翻译,成本要低得多,语义上也直接得多。
需要注意的问题:
如何限制客户端的查询能力?由于采用这样一种方案的ActiveRecord使得客户端拥有了最大化的自定义查询能力,我们一定需要有一些机制,可以限制这种能力:在Find(Criteria criteria)的实现端,在执行查询之前,需要根据一定的规则,验证criteria是否允许执行;在客户端的查询对象上,我们也可以有一些限制,比如,只允许某些字段作为查询条件,或者,有些ActiveRecord是只读的,不允许写操作。
以数据库的思维来构造查询条件。即使在允许的查询条件范围之内,由于不同的查询组合条件潜在地会导致不同语义的数据库查询被执行,不同的语义可能会导致不同的性能差异,因此,在客户端构造查询条件的时候,更大程度上,我们需要以数据库的思维来构造,而不仅仅是以业务的思维。
有人可能要问,客户端代码需要以数据库的思维来写,或者可能影响到数据层的执行效率,这样的设计是合理的吗?我觉得要看情况。
首先,ActiveRecord是允许和数据库紧耦合的,从这个角度,ActiveRecord的客户端本身就是允许通过ActiveRecord的外部接口,接触到数据库特定语义的。从这个角度来说,给予客户端一定的构造查询条件的自由度,至少是说得过去的。
其次,所谓ActiveRecord的客户端,对于不同的项目来说,对性能的要求可能有很大差异。比如,如果是一个公司内部项目,客户端的并发,整体的数据量也不是很大,则更多关注的可能是灵活性,那么,可以给客户端尽可能多的自由度;而如果是一个开放的WCF服务,或者并发或数据量很大,那么,可能应该尽可能的减少客户端的灵活性,Find(Criteria criteria)这样过于灵活的接口,也可能是不合适。
欢迎讨论!
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
那些年搞不懂的高深术语——依赖倒置•控制反转•依赖注入•面向接口编程
如何优雅的使用RabbitMQ
分布式锁1 Java常用技术方案
浅谈我对DDD领域驱动设计的理解
游戏编程十年总结(下)
【前端性能】高性能滚动 scroll 及页面渲染优化
验证码对抗之路及现有验证机制介绍
从零开始入门 K8s | 手把手带你理解 etcd
中文写程序,何陋之有?
NHibernate之旅(2):第一个NHibernate程序
公司的中场
谈谈如何从本质上理解sql语句, 存储过程,ORM之间的联系和取舍。
FFmpeg开发笔记(六十二)Windows给FFmpeg集成H.266编码器vvenc
Android 系统缺陷不完全点评
[一步一步MVC]第一回:使用ActionSelector控制Action的选择
.net环境下跨进程、高频率读写数据
第二个iPhone应用程序:“Say Hello”
从零开始学习jQuery (十一) 实战表单验证与自动完成提示插件
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
浏览过的版块
问答
科技
签约作者
程序园优秀签约作者
发帖
诉称
2025-5-29 19:33:58
关注
0
粉丝关注
11
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
敖可
9988
森萌黠
9996
堵赫然
9996
4
凶契帽
9996
5
处匈跑
9996
6
柴古香
9996
7
背竽
9996
8
斜素欣
9994
9
恐肩
9994
10
里豳朝
9994
查看更多