关键字:oo 面向对象的话题本来是个老话题了。只是看到还有不少人对这个问题有所困惑,我也就不吝浅薄,谈谈自己对面向对象的理解。还请大家在读过之后,能够不计鄙人的浅薄,多提宝贵意见。不断地争论和讨论是前进的根本动力。
面向对象的整套方法本来可以分为面向对象分析、面向对象设计、面向对象编程等。但是在这点上,我是赞同XP的开发思想的:代码就是所有的设计。因此,我更愿意把面向对象看作一个整体:一切最终落实到体现了面向对象思想的代码。基于此种考虑,在这里我也不区分OOA/OOD/OOP,而是泛指在面向对象思想指导下的软件开发及实现全过程。需要注意的是:“体现了面向对象思想的代码”和“面向对象的代码”是不同的概念, C#,java的语言特点决定了无论有没有面向对象的灵魂,其编码的“肉体”都是面向对象的。
关于OO的应用场合,还有很多人在争论。前些天看到还有人说三层结构/多层结构不适用于网站开发。从根本上讲,这和OO是不是适用于网站开基本上是同一个问题。因为,很显然,OO和N-Tier常常是一件事情的两个不同方面,使用OO却不使用多层结构是难以想象的,使用N-Tier却不使用OO那我就更加不知其可了。总之,在我看来,这两件事情是紧密相连的。退一步讲,将二者紧密联系在一起,如果不是必然的话,至少也应被看作是开发过程中的一个Best Practice。
下面谈谈我对OO + N-Tier的几个基本观点:
1)脱离了大量缓存和基于对象的业务逻辑的OO是没有意义的。
我以前看到一些同道在进行OO开发的时候,对象常常只在数据加载和保存中的出现。对象更像是一个盒子,在需要数据时,我们建立数据库连接,获取结果集或者DataReader/ResultReader,将从数据库获得的数据“填充”到对象中,然后再将对象返回给上层应用使用;在需要保存数据时,过程基本是对称的:我们把对象中的数据,一个字段一个字段读出来,生成参数化的或者直接字符串拼接的查询语句,建立数据库连接,提交更新到数据库。如果OO的主要内容就是这些的话,OO如果不能说是完全没有意义的话,起码意义也不大。我们在付出了编写了大量对象代码并且在存储加载时多一道手续的代码和性能代价之后,得到的好处只是使上层应用操作数据的代码可读性更好并且能够进行一定的类型强制和检查。这常常是很多开发人员对OO很困惑的原因:OO看起来很美,但是做了那么多事情,难道就是为了看起来很美吗?这同时也成为一些编程老手把OO看作华而不实代名词的原因:美是美了一点,但是代码多了,性能差了,让书呆子们去用吧。之所以出现这种局面,其根本原因在于“内存对象世界”没有提供太多的附加值。
大家应该注意到“内存对象世界”这一说法。在我看来,对象至少有两个世界,一个是“持久化对象世界”,一个是“内存对象世界”,这是由当今计算机的结构特点决定的:如果数据要长期保存,数据就必须被保存到可持久化的媒介中;如果要进行运算,数据就必须被加载到可运算寻址的媒介中。前者就是DB Server等管理的硬盘、磁带机...,后者就是内存。在DB Server为中心的开发中,大家倾向于把所有逻辑直接放置在最接近“持久化对象世界”的DB Server中,并主要以存储过程的形式存在。但是这样就一定是最合理的吗?尤其是对于网站应用?如果这样确实是合理的话,OO还有什么意义呢?是不是OO真的如某些人所说,只适合于图形绘制等特定领域?要回答这些问题,我们还是要看看哪些情况下,“内存对象世界”能够相对独立于“持久化对象世界”发挥其作用,这样“内存对象世界”就具备了独立于“持久化对象世界”之外的独立意义。
网站应用的特点是:看数据的人多,创建数据的人少。众所周知,恰恰就是这一点决定了缓存对于网站系统的重要性。对于主要以静态内容为主的小型简易网站,我们在这里就没有讨论的必要了。真正有人气的网站一定是具有动态增长的准静态内容(如新闻类网站,内容不断增加,但是本身很少修改)或者大量动态内容(如交易型的电子商务网站)的。对于前一种情况,通常有两种方式来加速其访问,一种是生成静态页面,一种是在内存中缓存页面内容。生成静态页面在性能上未必总是最好的选择。只有当数据多到内存中根本缓存不下,而这些数据又都有很大可能被用户访问时,生成静态页面才是较佳选择。在数据较多,但是并发并不多时,或者并发虽多,但关注的内容并不多时(如近两日新增信息或者近几日修改信息),页面缓存就是更好的选择。原因很简单,因为页面缓存的访问速度要明显快于静态页面。当然,有时候二者可以结合起来,这里就不多讲了。对于后一种情况——真正的较大型电子商务性网站,我们面对的是另一个问题:一些信息被以网页形式缓存,但这些信息本身的数据信息(如商品信息中的剩余数量,卖家Id等)常常需要被用到进行相关处理,如果只是进行了网页缓存,而没有进行对象缓存的话,缓存的意义就不打。在这种情况下,对象缓存就成为最好的选择。其实,在前一种情况下,页面缓存也可以以对象缓存的形式单独或者分级混合并存。