我对NHibernate的感受(2):何必到处都virtual
上一篇主要是在夸NHibernate实现的好,而这篇就完全是来抱怨的了。NHiberante有个毛病,就是如果是和数据库产生映射的类,就要求所有的public成员和protected成员必须是virtual的。请注意这里的要求有两个细节:
- 即使是方法,也必须标记为virtual
- 即时是不和数据库有映射关系的属性,也必须标记为virtual
这就让我觉得无厘头了,为什么没有任何关系的东西也要受到限制?我知道NHiberante要求将属性标记为virtual是为了延迟加载,因为只有这样它才能生成如上一篇文章中那样的延迟代理类,这样就可以实现只在第一次访问属性的时候才进行“加载”操作,从而访问数据库并获得数据,再填充字段。不过我认为这也不是合适的理由,因为这又关没有映射的属性,甚至方法什么事情呢?我在很长一段时间内一直没有想明白这个问题。
直到看了NHibernate开发团队成员Davy Brion的文章《Must Everything be Virtual with NHiberante?》之后,我才了解了他们的设计思路——虽然我还是不认同。我真的不喜欢到处virtual。
要求类中所有的公开成员(public/protected)都是virtual,是因为NHibernate想要保证在“访问任何公开成员”之前,数据已经被加载了。也就是说,无论您是想调用它的ToString方法,还是您自己写的辅助方法/属性,在真正进入您自定义的逻辑之前,数据肯定已经存在了——例如,存在于私有的域字段中:
public class Article
{
private string m_tagNames
public virtual string TagNames
{
get
{
return this.m_tagName;
}
set
{
this.m_tagNames = value;
}
} public void DoSomethingWithTagNames()
{
Console.WriteLine(this.m_tagNames);
}
}
虽然NHibernate可以在TagNames属性第一次访问时加载数据,但是如果我们的DoSomethingWithTagNames方法直接访问m_tagNames字段,数据自然无法加载了。因此,NHibernate必须确保有能力在代理类中覆盖DoSomethingWithTagNames方法才行。这就是virtual方法的由来。
但是在我看来,我们真的有多少情况会去访问私有字段呢?事实上对于大部分情况,我们会使用C#中“自动属性”特性来定义属性,这样自然只有属性,没有字段。即使我们使用了自定义的私有字段来保存属性的值,NHibernate也可以“叮嘱”我们应该访问属性,而不要直接访问私有字段——其实在编程上两者并没有差别。现在这样被强迫的感觉不好。
不过昨天我忽然想到,这似乎也是可以理解NHibernate这么做的原因:因为Hibernate要照顾到Java语言开发人员的使用感受——请注意是Hibernate,没有N。不管怎么说,NHibernate是从Hibernate移植过来的。NHiberante的主力开发人员Oren Eini曾在博客中写道(可惜一时没找到),NHiberante刻意与Hibernate的实现保持同步,这样容易进行双向的同步,例如Hibernate解决了一些bug或性能问题,也可以较为轻易地在NHibernate上修补。
不过这还是没有解释为什么Hibernate要一切都是virutal的原因啊。其实您只要看一下这段Java代码就应该明白了:
public class Product
{
private String m_tagNames; public String getTagNames()
{
return this.m_tagNames;
} public String setTagNames(String value)
{
this.m_tagNames = value;
}
}
这是上面C#中Product的等价Java代码。由于Java里没有“属性”概念,因此Java语言自身一直有一个“约定”:getXxx和setXxx两个方法即为一个属性。这个约定用在很多地方,如IDE就会把它当作是一个属性方便设置及导航,框架在进行序列化时候也知道哪些东西是“属性”。这“约定”本没有问题,但是这就给Java开发人员造成了一定困扰:使用起来实在是太麻烦了。例如,Product有个属性叫做ViewCount,我们想要把它加1,在C#中我们可以写:
this.ViewCount++;
而在Java中则必须是:
this.setViewCount(this.getViewCount() + 1);
因此,如果是你的话,在写Java代码的时候,是愿意使用getXxx()这样的方法,还是直接访问类中的私有字段?因此我认为,是Java语言的特性,导致Java开发人员倾向于直接访问类中的私有字段,从而导致Hibernate需要避免未加载的私有字段,进一步导致Hibernate的代理类会去覆盖所有的公开方法(只有方法,因为Java语言没有“属性”)——最终,由于NHibernate在“统一大业”上的策略,使得我们.NET开发人员也必须把所有成员标记为virtual,无论是方法还是属性。
您可能会说,但也没见Java程序员嚷嚷啊。没错,因为在Java语言中,默认情况下所有的成员都是virtual的。而在.NET平台下情况正好相反。因此在我看来,我们这里必须到处标记virtual所造成的不便,和Java语言本身有着非常大联系——我们需承受Java语言所带来的痛苦。
虽然我理解NHibernate,但这又怎能让我满意呢?
哦,对了。在未来的Java 7中,我们可歌可泣的Java语言终于有了a –> property这样的属性访问语法了。
可惜,迟了。
转自:http://blog.zhaojie.me/2009/09/my-view-of-nhibernate-2-virtually-everything.html
我对NHibernate的感受(2):何必到处都virtual的更多相关文章
- 我对NHibernate的感受(4):令人欣喜的Interceptor机制
之前谈了NHibernate的几个方面,似乎抱怨的居多,不过这次我想谈一下我对Interceptor的感受,则基本上都是好话了.这并不一定是说Interceptor设计的又多么好(事实上它使用起来还是 ...
- 到处都是坑的微信支付V3之 微信支付回调页面
据上次 到处都是坑的微信支付V3 后很多园友在被虐了千百遍后终于跳转到了亲切的微信支付界面,但输入密码支付后却不知道怎么处理了,接下来补上支付后的处理流程. 1. html中根据前台支付后反馈信息成功 ...
- 到处都是坑的微信支付V3
业务需要一个在微信上能付款的功能,于是乎想到了最普遍的支付宝,坑爹的是T与A是水火不容啊,默默的还是接微信支付吧,没想到从此掉进了连环坑…… 网上写微信支付接口的还是很多,PHP官方有(鄙视源码作者, ...
- 我对NHibernate的感受(3):有些尴尬的集合支持
既然是一个ORM框架,那么自然是将O这一端映射R上.至于集合,是O这方面最常见,也是R这一边非常容易表示的关系.例如,一个问题(Question)可以包含多个回答(Answer),于是我的代码里就有这 ...
- 我对NHibernate的感受(1):对延迟加载方式的误解
NHibernate是.NET平台上最著名的ORM框架,虽说出身于Java平台上的Hibernate,但是从外部看来这几乎就是一个.NET平台上的原生产品:有自己的社区,有自己的用户,有自己的商业支持 ...
- 不是什么时候都可以用栈来声明对象并使用(自动释放)——Delphi里到处都是编译器魔法,并且自动帮助实例化界面元素指针
一直都喜欢这样显示窗口,因为简单高效: void MainWidget::ShowMyWindow() { MyWidget form(this); form.resize(,); form.exec ...
- Java教程到处都是,究竟怎样能学好Java?
学习Java如何入门?学习教程要点是什么?如何精通?做好以下这些点,入门更快,掌握Java更轻松. Java必备基础知识 1.你需要精通面向对象分析与设计(OOA/OOD).涉及模式(GOF,J2EE ...
- 这是100年后火星的未来,到处都是CBD!
火星是个荒漠之地,尽管如此,最近几十年人类一直准备登录火星,然后殖民火星.随着科技的迅猛发展,感觉火星离我们越来越近了.不过,人类如何在火星上生存下去,这一直是科学家们最热衷的话题. 意大利建筑师 ...
- 在 NHibernate 中一切必须是 Virtual 的吗?
原文地址:Must Everything Be Virtual With NHibernate? 老赵在博文中 我对NHibernate的感受(2):何必到处都virtual 提到这篇文章,顺便翻译一 ...
随机推荐
- GreenPlum学习笔记:基础知识
一.介绍 GreenPlum分布式数据仓库,大规模并行计算技术. 无共享/MPP核心架构 Greenplum数据库软件将数据平均分布到系统的所有节点服务器上,所以节点存储每张表或表分区的部分行,所有数 ...
- 常用SQL Server 语句
常用SQL语句大全 1.//创建数据库 CREATE DATABASE DBName 2.//删除数据库 DROP DATABASE DBName 3.//备份SQL SERVER --- 创建 ...
- CCF CSP 201612-2 工资计算
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201612-2 工资计算 问题描述 小明的公司每个月给小明发工资,而小明拿到的工资为交完个人所 ...
- Rookey.Frame之菜单设置
在上一篇博文 Rookey.Frame企业级快速开发框架开源了 中我们介绍了Rookey.Frame极速开发框架的最新更新及开源介绍,后面慢慢介绍该框架的使用方法,本人文笔不好,写得不够好的地方请大家 ...
- lr参数化取值与连接数据库
TXT文本,EXCEL表格以及数据库中的表都可以作为参数的数据集载体,LR都是支持的. 特别提醒: 1.在形成数据池之后,数据库中的数据变化不会影响数据池中的数据. 2.数据文件一定要以一个空行结束, ...
- 005 爬虫(requests与beautifulSoup库的使用)
一:知识点 1.安装requests库 2.Brautiful soup 可以提供一些简单的,python式的函数来处理导航,搜索,修改分析树等功能. 她是一个工具箱,通过解析文档为用户提供需要抓去的 ...
- Mac下思维导图Xmind使用入门
1.软件下载 中文官网地址: http://www.xmindchina.net   安装过程比较傻瓜化,这里就不截图了. 2.用Xmind设计软件模块: 1>.新建一个思维导图,如下图,选 ...
- CentOS查看内核版本、系统版本、系统位数
http://blog.51cto.com/ultrasql/1640435
- Maven项目使用阿里云的Maven库
Maven项目下载一些jar包非常慢,有时候一个项目能下一个上午,因此可以考虑使用阿里云的Maven库,因为是国内的,所以下载速度非常酷 单个项目使用阿里云的Maven库: pom文件中 <!- ...
- JAVAEE——宜立方商城02:服务中间件dubbo、工程改造为基于soa架构、商品列表实现
1. 学习计划 第二天:商品列表功能实现 1.服务中间件dubbo 2.工程改造为基于soa架构 3.商品列表查询功能实现. 2. 将工程改造为SOA架构 2.1. 分析 由于宜立方商城是基于soa的 ...