上一篇文章主要是在夸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_tagNamespublic 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这样的属性访问语法了。

转载于:https://www.cnblogs.com/wangjei155/archive/2009/09/29/1576542.html

NHibernate :何必到处都virtual相关推荐

  1. 我对NHibernate的感受(2):何必到处都virtual

    上一篇主要是在夸NHibernate实现的好,而这篇就完全是来抱怨的了.NHiberante有个毛病,就是如果是和数据库产生映射的类,就要求所有的public成员和protected成员必须是virt ...

  2. 宜信创始人唐宁:技术到处都是,关键看怎么用

     宜信创始人唐宁:技术到处都是,关键看怎么用 极客公园 2017-06-02 16:15 阅读:4443 摘要:作者:「痛点是什么?」5月26日下午的北大斯坦福中心,这是宜信创始人唐宁口中出现频率 ...

  3. 最近大街上,到处都是X团的地推

    小文说,最近大街上,到处都是X团的地推,成群结队的,拉着每一个路人推销他们的软件,忽悠着你下载他们的APP. 小文昨天中午出去吃饭,五.六个X团的地推,把一个漂亮女孩围在中间,各个都是轻佻的语气,拜托 ...

  4. 不要到处都用@Autowired啦

    相信大部分人项目只要用了spring框架,肯定到处都是@Autowired. 注意: spring4.3以后就可以省略@Autowired了,全部更新内容: 地址:其中跟新内容如下 这是什么意思呢,翻 ...

  5. 说一说ffmpeg到处都在使用的ff_thread_once函数

    从名字就能知道ff_thread_once函数的作用,就是保证在多线程调用的时候,函数只执行一次 FFmpeg中是使用经典的double check来保证函数只执行一次的,我们来跟踪下函数看下具体的实 ...

  6. shields 徽标_到处都有平面徽标

    shields 徽标 重点 (Top highlight) Companies invest a lot of time, money and energy trying to make audien ...

  7. openai-gpt_为什么到处都看到GPT-3?

    openai-gpt Disclaimer: My opinions are informed by my experience maintaining Cortex, an open source ...

  8. 为什么到处都在推python_Python为什么能取得越来越超然的地位

    展开全部 Python在人工智能领域的e69da5e887aa62616964757a686964616f31333365643632应用 2016年开发语言使用情况统计 机器学习与数据科学领域各语言 ...

  9. 到处都是“公馆”,中国小区命名为何如此“没文化”?

    特约作者 | 熊志 怪异难懂.刻意夸大.封建色彩.崇洋媚外.怪诞离奇--日前西安下发<关于做好我市清理整治不规范地名工作的通知>,对地名进行了摸底排查,并着手上报清理不规范地名,不少小区都 ...

最新文章

  1. 带你100% 地了解 Redis 6.0 的客户端缓存
  2. AlertDialog.Builder setCancelable用法
  3. JDBC(二)——使用IDEA连接数据库、数据库连接池
  4. zbb20170606 oracle 查看空表
  5. OJ1045: 数值统计(c语言)
  6. python安装包的方法与图解_Python包的几种安装方法,方式
  7. 自定义View(四) ViewGroup 动态添加变长Tag标签 支持自动换行
  8. php加密密码解析,php密码加密解密
  9. 2.LVS的三种工作模式_NAT模式
  10. Excel根据公式生成插入语句
  11. html生成图片有色差,引起打印的产品和电脑图片有色差的原因有哪些?
  12. windows创建服务删除服务
  13. oracle中is not null,oracle之is null和is not null的优化
  14. Python爬虫——查询英语四、六级成绩
  15. 【转】中国只有俩导演,一个叫贾樟柯,一个叫姜文
  16. 对Java枚举与静态变量扩展,以及异步回调处理思考
  17. 用友U9二开附件自定义下载2下载附件
  18. 关于小程序 scroll
  19. html拖拽模态框,bootstrap模态框实现拖拽效果
  20. vue-router路由模式有几种?

热门文章

  1. 无人驾驶是好,但晕车咋办?
  2. Java运行时数据区域
  3. 如何在阿里云上安全的存放您的配置
  4. Portainer容器管理软件,安装
  5. Linux SSh scp使用【远程文件/目录的传输】
  6. thinkphp ajax 实例 实现
  7. C#相等性 - 三个方法和一个接口
  8. 快速上手Spring WebFlux框架
  9. JavaScript HTML5脚本编程——“跨文档消息传递”的注意要点
  10. 查询各个商品分类中各有多少商品的SQL语句