Why OO+多层结构? 来自实战的深入思考...(请求置顶)

aafshzj 2006-09-19 01:38:42
面向对象的话题本来是个老话题了。只是看到还有不少人对这个问题有所困惑,我也就不吝浅薄,谈谈自己对面向对象的理解。还请大家在读过之后,能够不计鄙人的浅薄,多提宝贵意见。不断地争论和讨论是前进的根本动力。

(更多精彩,请访问我的博客:http://blog.csdn.net/aafshzj/)

面向对象的整套方法本来可以分为面向对象分析、面向对象设计、面向对象编程等。但是在这点上,我是赞同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等)常常需要被用到进行相关处理,如果只是进行了网页缓存,而没有进行对象缓存的话,缓存的意义就不打。在这种情况下,对象缓存就成为最好的选择。其实,在前一种情况下,页面缓存也可以以对象缓存的形式单独或者分级混合并存。

回到我前面提出的观点:“脱离了大量缓存和基于对象的业务逻辑的OO是没有意义的”。其道理是显而易见的,只有使用了大量缓存和基于对象的业务逻辑,建立一个OO结构的收益才远大于我们付出的代价,OO本身所在的“内存对象世界”也才具备了脱离“持久化对象世界”而存在的根本意义。如果我们能把大量适合放在内存中的业务逻辑搬移到应用内存中(而不是DB Server)的话,那效果就更好。当然也有一些操作不适合放在应用逻辑中,如针对特别大量数据的非个性化的成批更新操作。至于什么叫大量,这取决于性能的考虑和实证。将很多业务逻辑从数据库搬移到应用内存中是可行的,尤其是对于在执行前要根据很有限的数据条目进行大量判断来决定是否实质性产生某种数据改变的逻辑更是如此。代价是速度可能较存储过程差一点点,但是却避免了因为大量不符合规则从而根本不会产生实质数据改变的无效调用而导致的应用服务器到数据服务器的网络往复,二者相比,无谓的往复往往代价要高得多。对于现实的电子商务网站,这一点是非常有价值的。



2)OO并不是低性能的代名词,设计合理的OO会带来意想不到的高性能。

OO并不是低性能的代名词。恰恰相反,很多时候我都把OO当作我提升网站性能的基本武器:通过结构合理而算法高效的对象缓存技术以及与对象结合并在同一地址空间中执行的业务逻辑,我们往往能够轻易地提升系统的性能。当然,一切的前提在于正确的设计,这不断适用于OO,也适用于世间一切,没有什么东西脱离了其实现的细节而万岁千古!

以我们最近完成的一个较大型电子商务网站为例(目前日均订单〉12000,成交订单笔数在3000左右,而且最近增长势头很好),在运行近三个月后,该网站在Alexa的速度统计已经从早先的very slow(平均一个页面6~7妙),经过slow(Alexa的数据是累计的,所以不是立即跳变),上升到average(平均一个页面2.0s)。与此同时,DB Server的CPU Usage从原来的平均80%急剧的下降到平均10%!在现有系统中,基本上除了一些大批量数据移动和数据库服务器段数据分页查询之外,所有业务逻辑均存在于我们的应用逻辑中。这大概是违法很多朋友的开发直觉的。我经常听到的是:用存储过程吧,为了性能...我不是在一切场合都反对使用存储过程。但是我们必须清楚,每一种方法的优点是什么?缺点是什么?条件是什么?什么场合适用?什么场合不会适用,什么场合二者应该在更细微的场景/场合下分别或者混合使用。这有点象物理中的定理:谁见过没有适用条件的定理?



3)如果你关注Scale out的能力,你就更应该考虑OO。

现实世界的网站应用系统,都必须考虑Scalability问题,除非业务永不增长。只要业务会增长,使用人数不断增多,服务器就一定会很快达到性能和并发极限。解决这个问题,通常只有两个办法:Scale up——买更好的服务器,而这往往因其代价过于高昂而不现实;Scale out——买更多的服务器,这往往是最终的实际选择。但是Scale out始终面临着数据集中(就算是拆分过的数据仍然各自相对集中,能做到无限随意拆分吗)的问题。如果大量的逻辑放在数据库服务器一端,我相信很快数据库服务器就会使得系统失去Scale out的能力和可能。因此,要保证Scale out的能力就必须保证数据库(当然,必要的拆分策略也很重要,但那属于另一个话题)只处理实质性的数据提交和不可避免的数据查询,对于能够避免的数据查询和非实质性数据提交都应该想办法予以避免。这其实和我们上面所说的“脱离了大量缓存和基于对象的业务逻辑的OO是没有意义的”刚好结合起来,成为一举夺得的美事。



4)OO + N-Tier的基本思想乃至软件开发方法的所有其他动力是对逻辑聚合和复用地不断追求。

大家都知道,软件开发的分析设计方法一直在不端演化,新的概念不断涌现。软件开发也从最早的直线条的机器语言,到面向过程的汇编语言,再到面向对象的对象化分析设计及编程(继承、接口、多态),以及后来的DP(设计模式)、AOP(面向方面的编程)...。一系列的演化,确实让人有眼花缭乱之惑何从入手之惑。那么在这一演化过程中,一以贯之的是什么?始终不变的又是什么呢?

...
...全文
1984 76 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
76 条回复
切换为时间正序
请发表友善的回复…
发表回复
amandag 2007-04-27
  • 打赏
  • 举报
回复
不错,有启发,谢谢
z_teny 2007-04-27
  • 打赏
  • 举报
回复
请问下:OOP跟缓存存在着什么样的关系,我觉得一直在围绕着缓存在讲
zhongwanli 2007-04-26
  • 打赏
  • 举报
回复
需求是不断被激发的,所以OO所面临的应该是不断变化的需求。
DP,AOP也是为此。
fstars 2007-04-25
  • 打赏
  • 举报
回复
正在关注OO,不过确实是要看项目规模了,一个就用1年的软件,还是开发的越快越好了。天天都在干这种事,郁闷。
haixj 2007-04-25
  • 打赏
  • 举报
回复
牛!不过完全的OO对于我们小公司混的没时间搞啊,为了MONEY也就管不了那么多了,客户能用就行
aafshzj 2007-04-18
  • 打赏
  • 举报
回复
自己顶!
aafshzj 2007-03-15
  • 打赏
  • 举报
回复
thoughtworks() ( ) :
感谢你的留言。

静态页面也是可以搞得,但要对所有的页面内容进行分析:哪些内容是基本不变的,哪些内容是经常变化的,哪些内容中的哪一部分是变化频繁的....

有一些网站除了管理页面,几乎不需要动态页面。有的则必须使用动态页面。大多数情况介于二者之间。

即便是静态页面往往(除非极端情况)也需要好的架构,因为静态页面在大多数时候还是根据可维护的数据生成的。只不过因为变化缓慢,可以直接生成html页面罢了。
michney 2007-03-15
  • 打赏
  • 举报
回复
mark 一下,以后研究
sse33 2007-03-14
  • 打赏
  • 举报
回复
LZ的言论开拓了我的视野,注意到oo和缓存的联系,但我个人觉得帖子的精髓不在LZ发表的文章,而是从而引发oo关于性能和扩张性矛盾的讨论,给我这些菜鸟可以更深的理解我为什么要用oo。延展性扩展性是基础,性能是关键。
thoughtworks 2007-03-14
  • 打赏
  • 举报
回复
补充一下,我认为持久化对象世界这个说法中的“持久化”值得考虑,,,这个持久该怎么定性定量????持久有多长?永远?或者维持1秒钟便足够?
thoughtworks 2007-03-14
  • 打赏
  • 举报
回复
有见地!我刚加入了一个所谓的asp.net团队搞一个站点,那些人想也不想,就要搞什么静态页面,搞一大堆存储过程,我在想这玩意儿真有那么神么,现在搞得很混乱,我要接手搞代码维护,连个开发文档都没有,全要让我自己琢磨那些匪夷所思的东西,貌似他们自己都不知道当初是怎么写出来的,站点开通了几周竟然连负荷测试,访问量都没统计测试……,,,,就闭着眼睛在那说静态的快,存储过程快,,,,……没办法,刚进去,没有任何说话的分量……你要是我的技术主管,那我铁定跟你干!
aafshzj 2007-03-14
  • 打赏
  • 举报
回复
sse33(宁静至远) :
感谢你的留言。有一点大家可以讨论:那就是“性能和扩张性矛盾”吗?

我的个人感觉是:绝大多数现实情况(也就是非极端情况)下,性能和扩展性并不是0角度的契合,但也不是180度的矛盾。只不过要将二者同时驯服,需要在架构上好好下点功夫。

我的一点粗浅认识是:所有的指标,本质上都是对另一个指标:“个人/团队智力和经验”的挑战;我们所有的权衡与其说是在各项项目指标之间进行,不如说是在各项项目指标+“个人/团队智力和经验”指标之间权衡。

sunnf 2007-03-13
  • 打赏
  • 举报
回复
精采!!!继续关注。学习再学习!
spgoal 2007-03-12
  • 打赏
  • 举报
回复
我觉得楼主的文章偏重于性能方面,个人认为,OO的出现的原因是为了减少需求变更所带来的返工成本,一个好的OO架构应该是低耦合高内聚的,具有高扩展性,而要达到这个目标,必须分层,是各个类的职责清晰,减少依赖性,但这样带来的结果就是性能的影响,所以我觉得性能与高扩展性是一对矛盾,而能缓解这个矛盾的手段之一就是楼主所说的建立完善的缓存机制
aafshzj 2007-03-12
  • 打赏
  • 举报
回复
感谢各位的指教。smartcreater() 同学有点激动,呵呵,不过没关系。

其实smartcreater() 同学的基本论点,究其根本而言,我都不反对。因此,我真不知道我们的所谓争议在哪里?

关于OO和性能的关系问题,我前面其实已经回答了。OO确实不是为了解决性能问题才出现。但是在现实中,因为不得要领的应用OO而导致性能下降的例子比比皆是。因此,将OO与性能问题结合起来讨论很有必要。

OO的根本思想,就我的理解,就是用领域问题最自然的结构来描述问题并建立起解决问题的模型。用smartcreater() 同学的说法,这大概就是“更合理的用计算机语言来描述现实世界”,而在我看来,就是“用现实世界最自然的方式来描述业务逻辑”。个人觉得:这两种说法本来就没什么本质上的区别。我的一点个人感觉是:smartcreater() 同学对“业务逻辑”或者说“业务”似乎存在有点狭隘的理解,业务的感念其实很广泛:所有的类型和模型无论其所在层次和领域,都服务于其自身的特定“业务”。在这一点上,smartcreater() 同学在“.Net Framework中包含如此丰富的基础类库,从底层到UI,一应俱全OO设计”一句中提到的所有类型也概莫能外。

至于“可以楼主的经历大多在网站层面! 才出此言!!”,事实是,网站相关的开发经历顶多占我个人开发经历的1/3。
jetxia 2007-03-10
  • 打赏
  • 举报
回复
看了 楼主和各位兄弟的回复
OO是何其博大,大家对OO基本上都是从一个角度看待整体,想想我们小时候学的盲人论象,大家所说的很有道理,站在某一点上来说也都是正确的,但是如果从OO反过来看待这些问题的话,在使用中有很多东西和OO是有一定的悖逆的。鉴于此,偶认为应该去接受更多的看待问题不同角度的分析结果,然后在实际应用中取其适用之处。
smartcreater 2007-03-09
  • 打赏
  • 举报
回复
"脱离了大量缓存和基于对象的业务逻辑的OO是没有意义的"?
是这样的吗?

OO的提出是因为软件规模的日益庞大,越来越复杂的基础上提出的,它的基本思想是更合理的用计算机语言来描述现实世界。
Cache与OO没有本质上的关系, Cache的出现无非是解决速度上的问题,而OO的目的不是加快响应速度,OO也不只是针对业务逻辑而诞生的。

.Net Framework中包含如此丰富的基础类库,从底层到UI,一应俱全OO设计;
它的OO没有"缓存"的概念,也没有"业务逻辑"的概念,难道它的这些都没有意义吗?

可以楼主的经历大多在网站层面! 才出此言!!
sunnf 2007-03-09
  • 打赏
  • 举报
回复
好!!
Alden 2007-02-08
  • 打赏
  • 举报
回复
不错,值得一看
aafshzj 2007-02-07
  • 打赏
  • 举报
回复
春节前最后一顶
加载更多回复(56)

13,190

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 分析与设计
社区管理员
  • 分析与设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧