凑热闹,也来说对象持久化以及ORM

这几天有比较热闹起来,最近新书进入收尾阶段空闲时间也有了,所以也来凑凑热闹,其实主要是看过以下面两个Post,有些感想,所以写下来也欢迎各位大中小虾批评指正。
一篇是:比较Hibernate和ADO.net 2.0,问?Hibernate还有什么特性更值得期待?
一篇是:域模型向左走(充血),向右走(贫血) 

很多大虾都提出了自己的主张看法,针对这这两篇主题已经有很充分的讨论鸟,这里我只想针对其中所涉及的两个方面的问题说说自己的看法
一个是对象持久化,一个是ORM。

首先,什么是对象持久化?为什么要持久化对象?

针对这个问题主要是在第一篇里的徐大侠所提的ADO.NET2.0对对象持久化的支持的问题。所谓的对象持久化,首先,这个必须是在完全OOD,OOA,OOP的程序里才可能出现的概念,当然,没有对象何来的持久化?我们在设计程序的时候,通过用例对问题的领域进行描述,就我个人的观点来说,其实用例在领域模型建立的过程中或者是我们建立一个问题域的过程当中作用是最大的,基本上再细化之后所挖掘出来的东西就很难OO的去理解了(最终到了数据库这个级别的时候是没法OO的,比如SqlHelper,基本上的结构就是一大堆的静态方法,其实是不用搞什么用力分析了的)。而程序在运行的过程当中,所有的类和对象都是存储在内存当中的,而类的状态(也就是属性)在内存当中是无法永久存在的,因为内存的可挥发性,所以当程序重新启动后是无法保持所有对象的状态,比如我们在程序开始默认创建了10个用户的对象,但是在运行的过程中修改了一个用户的昵称属性,这个时候如果我们重新启动程序,那么这个用户的昵称属性被改变后的状态是没有办法保存的。这个时候我们就需要将这个对象的状态(所有属性的值-----也不一定是所有,因为有的属性是依据其他属性的,最终还是看设计而言,反正就是在设计上需要保存下来的属性)存储下来,并且可以在需要的时候随时加载到内存中。这个就是对象的持久化。

那么我们怎么来持久化对象呢?那方法就多了,我们可以通过序列化将类平面化后存储在文件系统,或者通过数据库组件将对象的状态存储到数据库中。我们会在数据库中设计表结构来存储对象的属性,并且能够在数据库中快速索引到某一个对象存储的状态,并且快速恢复到内存中。

回过头来我们在.NET中设计程序的时候很多时候的思考方式确是反过来的,我们先用数据库设计工具设计好数据库结构,然后再来开始设计类,这个时候很多人会感觉到OO很别扭,怎么会别扭呢?其实就是我们在设计数据库的时候少了一个前提,数据库存储的是什么数据?我们要在数据库里存储对象的状态,所以我们必须要有了对象才能够开始数据库的设计,而这个设计的过程其实也就是一个OR Mapping的设计过程,类设计应该作为数据库设计的前提,类的结构是数据库结构设计的一个约束,我们必须在这个约束下来设计数据库,并且在这个前提下调优,并且也是在这个前提下才能够确定那些字段视需要冗余的,那些需要分表,那些应该作为主键。如果把这个过程反了过来,就会出向两种情况,要么就是为了设计的完善而在设计数据库的时候要做一次分析,然后再设计类的时候还要设计一次造成时间需求扩大,所以这个时候就会有很多人感到,真是过度设计了啊。要么就是因为在设计数据库的时候考虑不周(肯定的,都没分析就开始做周全了就见鬼了),然后在设计完类之后就会发现两头都不对劲,然后两头改。

最后的结果就是说OO不好,预先设计浪费时间,用起来别扭,其实不是OO不对,而是人不对,因为发现这些问题的时候我们完全都把过程搞反了,而这些错误是我们常犯的,而且很多时候还会人穷怪屋畸的责备OO的问题,其实OO并没有问题,我们的问题确是更大一些。

设计为什么要自顶向下?这里我们要特定在有一定业务逻辑的业务系统,写驱动的牛人就不必看这段了。
因为所谓的业务系统一定是以符合业务的规范,用业务作为设计的约束才能够真正的做好一个系统,至于实现的细节,哇塞,大家都是出来靠写程序吃饭的,读写数据库,写日志........说白了程序在最终实现的时候都是这些东西,至于事务啊,线程安全啊,跨进程同步啊,这些啰唆的问题就是在设计架构的时候考虑的问题了,而这些也是架构师要考虑的问题。而比如EnterpriseLab就是做这个的,当然我们自己来实现一个类似的东西也没有关系,总之这是个大框架,可复用的,我们只需要设计好业务相关的类放进去就可以了(理想情况,大多是时候我们还是要自己做很多啰唆的事情)。

自顶向下能不能XP?当然,我们完全可以快速的搭建好框架,然后写出测试用例,在类中都用伪逻辑实现,这个时候数据库都没开始设计呢我们就可以开始测试了,够XP了吧,我们可以在开始的时候就对业务设计做充分的设计,并且在得到稳定的同时最后去完成数据库的设计以及实现持久化。(数据库最好要稳固,不要动不动就来个大变样,万一休假一个星期去旅游一趟回来见他就不认识了就太糟糕了)所以其实自顶向下更需要单元测试,更加的XP。

而且现在对于持久化的功能有ORM这个利器,我们完全可以用AOP将持久化的能力注入我们我么设计的类中去,让对象具备被持久化的能力。


这下我们谈到ORM了,对于什么是ORM我们不用多说了,到处都是解释。
按我的理解,ORM就是一个将数据库的结构转化成对象的状态的转化器。
那我们用ORM来干什么呢?我认为ORM的作用就是为对象实现持久化的能力,如果这样子理解的话即使是我们仅仅把ORM当作一个好用的CUID工具来使用也不会有太大的问题,当然如果对ORM使用比较熟练的话可以通过配置完成持久化的功能当然更好。所以其实不管贫血还是充血,FatService还是ThinService,只要我们在设计的时候延续正确的方法,那么我们就不会感觉到别扭。

理想和现实是有差距的,首先,此方法遗留系统不适用,太大的遗留系统这样子重构的话,那不是人能干的活。其次没有好的架构设计师的话没法用,对业务的理解都有问题,分析用例类没找对........结果还是痛苦。再次编码的程序员素质要足够,不然理解不到位,使用起来还是这么的别扭(起码在编码人员看起来是)。

邓爷爷说:不管白猫黑猫,能逮住耗儿的就是好猫。这是实用主义者的宝典,但是我们不能因为这样子就裹足不前,因为现实的约束就不去追求实现的优美,逮住耗儿也要看是轻轻松松信手拈来还是一路筋斗鼻青脸肿的逮住耗儿,能够完善我们的设计为什么不去完善呢?

注意:本文由本人原创,仅代表本人此时的看法以及观点,将来有什么变化,谁知道呢?

posted on 2007-09-15 00:03  亚历山大同志  阅读(5642)  评论(37编辑  收藏  举报

导航