何必非要OOP?

这篇文章其实是笔者多年以来的疑问感悟所成,估计各位居于不同语言阵营中的同道们也会有不少类似的疑问,愿此文抛砖引玉,与大家共同探讨OOP与过程式编程的是是非非。

笔者转向Java Web编程前从事的是传统的Delphi C/S编程。转过来后就觉得J2EE分层太多,每到更改,每层几乎都要涉及,相当麻烦且易出错。在Java Web之余,又涉及了一些ASP、PHP之类的东西,才发觉Web编程也可如此简单,不禁对J2EE产生了很大的疑问:本来可以简单实现的东西,何必搞得那么复杂?
近两年OO水平上涨后才逐渐领会到其中玄机。OO与分层最重要的好处其实业务逻辑及类库的复用!OOP将数据存储、业务逻辑、表示层分离,就可以适应多种数据存储方式与表示层技术的变化。比方说,你就可以选用多种数据库、XML甚至文本!也可以选择WEB、Rich Client以至于手机、PDA。当存储层与表示层变化时,业务层几乎可以保持不变。原因其实也简单:传统的过程式编程是把他们在一块写,而OO则是分开来写。而天下事总是利弊相当,OOP的高适应性也就必然为其带来高度的复杂与费时,甚至修改时的麻烦。综上所述,OOP其实是便于扩展而不适于修改。原因简单之极,写在一起的改起来只需改一处,分开写的改起来则要改每一处。
这一点上顺便提一下Sun的经典J2EE。经典J2EE其实是把OOP做到了极致,除却上述坚决的三层分离外,EJB更把数据存储层的事务与业务层的分布式特性加入其中。这对大型系统而言绝对是极大的福音。而中小型系统基本上是不需要事务与分布式的,这样一搞就让J2EE非常复杂。于是Sun的经典J2EE遭到了绝大多数中小系统应用开发者一致的口诛笔伐。可到了真正的企业级领域,J2EE的地位却难以撼动。这充分说明了OOP的极致是适应性与复杂性的综合体。这好比生物界中的生物,适应性越高的生物(如人类)必然越复杂。

是否采用OOP,OOP用到什么程度,要因软件产品的定位而论。如果考虑的是扩展性,业务逻辑相对固定,而存储层、表示层变化多的情况下,OOP当是不二之选;而存储层、表示层相对固定,业务逻辑变化大的情况下,则应选用过程式编程。如果二者变化程度均衡,则可采用MS骑墙式的方法。笔者这番大胆言论其实并非由理论推导而来,而缘于对当今软件界的实际观察。真正的企业级开发无疑J2EE是主导,这符合第一种情况;而变化迅速的互联网界则以PHP为王,小型桌面系统至今仍以VB、PB、Delphi为佳,这符合第二种情况;而中型系统,.NET发展得最好,这正是第三种情况。
所以我们搞软件的诸位同道,居于不同的阵营中,不免终日比短较长,其实是没有必要的。各种语言都有他的优势与适用范围。做好产品、服务的市场定位与技术定位,扬长避短才是明智之举。

楼主思想非常深刻,非常有道理。

但是有几点还是要讨论一下:
SUN的J2EE核心模式我在其他帖子曾经提过,其实并不是完全OO的,这个问题就不多谈。

使用OO有两个根本原因:
(1) OO实际为了应付快速变化的需求,如果你认为你的需求不会经常变化,而且是事先已经设定好,可以不用OO,所以,我曾经说,游戏编程水平不一定有企业编程水平高,因为,游戏软件都是事先设计好,在运行阶段,几乎无需接受客户检验和需求多变的困扰,游戏用户只是按照游戏规则玩。

(2) OO更符合人类自然习惯思考,对象是人类对需求抽象表达的最自然的方式,相反,那些变量、数据等等都需要经过所谓符号培训才能培养,而且对象继承分类更符合我们日常表达的语言,类如:飞机,我们知道属于交通工具,交通工具就是一个抽象接口,两者继承关系就明朗,多方便!


关于楼主提到的跨层开发效率不高问题,其实原因很简单,产生这个问题还是OO不彻底,这不是OO思想问题,而是Java以前在SUN主导下走了弯路的原因,所以OO大师Martin fowler才极力推荐Ruby on Rails这个新的OO语言,言下之意,他们对Java/.NET都有些失望。

那么现阶段如何解决楼主提到的开发效率不高问题?Evans DDD就提出了领域建模的思想,领域建模前提必须是分层,DDD是一种MDD事先,将来是DSL,这些都是OO思想发挥到极致的一种快速迅速的表现。

所以,我个人认为:切不能因为OO征途中出现问题,就怀疑路线是否正确?开始打退堂鼓,更不能采取过程和OO两种混合设计的思维,因为这两种方式代表两种思维,是水与火,不匹配的,如果两个都做,OO肯定做不好。

OO可以直接从一个人刚学计算机开始培养,而不是培养学生数据结构等走弯路的分析思维。这就是当今中国计算机教育之怪状,也是过程思维在我国软件阴魂不散的根本原因,也是我们软件相差国外的根本原因,也是软件业不能振兴的原因之一。


呵呵,楼主有个问题想跟你探讨一下
你说是大型企业应用容易变化还是小型应用更具备稳定性??
你见过大型企业应用换过数据库么??
会不会有开发需要一年以上的系统中途修改更改整个架构的??

所以有的时候真的怀疑J2EE
因为大型系统缺乏变更,而J2EE讲的是适应变更
这好像有些自相矛盾
我觉得J2EE更主要的是解决了集群的问题
要不然根本就不会有人用。

大型应用的核心业务逻辑是比较稳定的。比如银行的存取、转帐等核心业务,上百年都不会改变。但会从单机版演化为内部网络版,以至于Internet版、无线版。并发数会由几十到几千以至于上万计。如果系统解耦得好,就可以在业务逻辑极小变动的情况下完成升级。
大型应用的确极少换数据库。可如果你做的是产品或平台,不同的用户要求的是不一样的数据库,你就必须让你的产品或平台具有适应多种数据库的能力。
中途换架构,除非老板有足够的钱撑住,否则必死无疑。所谓是“千万条路你千万别回头”。
再强调一次,J2EE的长处是大型复杂系统。国内大多数项目都是中小型应用,用J2EE当然快不了。但其实所谓中小型应用与大型应用并没有绝对的界线,今天的中小型应用也许将来会演变成大型应用。如果你OO得好,届时就不会费很多力气。如果原先是过程式的原型系统,那就得彻底重构了。

感谢banq的讨论及意见!

在这个时代,OO是软件设计的终极之路。用OO设计具有良好适应能力的软件,是每个软件工匠的追求。
但现实中,我们往往面对太多的需求与变化,太少的时间与精力。很多时候只能采取过程式的权宜之计。以笔者浅见,OO的短期开发效率目前尚未能够与过程式比肩。这就迫使我们在时间紧张的情况下用过程式技术(如PHP)完成原型系统,待系统业务逻辑稳定,系统推开之后,立即用OO的方式重构(如J2EE),以适应系统发展的长远之计。这的确是软件设计师的无奈,不过或许世间道路总是曲折前行,软件开发之路亦然。

顺便说句题外话,此文在JavaEye一发,旋即作“新手帖”删除,实是愤怒。
现今的JavaEye,只要一提到Sun、EJB、JSF,或是与WebWork、Hibernate、Spring、Eclipse、RoR作对的东西,删无赦。这实在不是真正的技术人员所为。
迷过一阵JavaEye,后来才发觉其倾向性太强,不是真正热爱思考、求真务实的自由软件精神之所在,不理它了。
以前风传banq会删帖,也就敬而远之。来了几次,帖子都在,说明是谣传。而且banq很热心,水平参差不齐的问题都努力给大家回复,再次感谢!

号召真正热爱编程的同道们多来jdon相会!
[该贴被lgx522于2007年02月14日 18:24修改过]
[该贴被lgx522于2007年02月14日 18:25修改过]

>再强调一次,J2EE的长处是大型复杂系统。
同意你这个观点,J2EE属于重量级开发,我可以说如果开发周期不超过1年的项目使用J2EE基本就是浪费金钱,不光是自己的也是用户的。

不过有些地方也不敢苟同。至今为止在大型以及超大型程序设计开发中仍大量使用面对过程的开发过程,而且也具备很强的可扩展性(比如银行业务,证券及期货业务,现在也可以手机炒股,手机银行),我所接触的在AS400,Rs9000,Rs6000下的开发基本上也仍然采用面对数据流的设计方法。当然不排除历史原因,但是也从一个侧面反映出面向数据的有其独特的魅力。

我觉得人们习惯于否定一种东西来肯定另外一种东西,但是有的时候两者并不是真的矛盾。程序=数据+算法,这句话只要学计算机的应当都听过,至今为止还没有人对这个提出过异议。用户使用计算机的目的就是要用它解决问题,计算数据,更快更准确的计算数据。那么以数据作为面对的处理的东西是必然的事情,关心数据处理数据的过程也是显而易见的。oo不过是让我们可以以生活的角度来面对计算机,对程序员的要求降到更低,他们最终可以用生活化的方式来处理数据,而不必象过去那样翻译成计算机的语言。(比如设计人,过去可能需要面对身高,年龄等等枯燥的数据,并将之翻译成x、y。现在只需要定义persion)。从计算机的发展而言,也是一种这样的趋势,最开始的汇编,到C再到C++,到现在的java,C都是一步步将对程序员的要求降低下来(这没有什么贬义),但是汇编,c,c++由此消失了么??在底层,系统级,他们仍然具备旺盛的生命力(至少我没有看到java做的操作系统,c++的基本上也很少)。

所以我觉得jdon现在有种非oo就是不正确的论调,这个想法我觉得没有必要,软件最终是给人用,用户关心的真的是什么,这个才是我们率先的考虑的。

很高兴能找到这个论坛,这里的人都很友善,
回答问题也很专业。我目前还是个菜鸟,
以后扎根在这学习了!

大师的演讲都是非常深刻的,鄙人就是想找一个好多的基于OO的分析与设计的案例,以供学习。自己对OO的渴望是极端的~谢谢!Bang大哥!

何必非要OOP?我也曾有此一问。

我完全赞同使用OOP,并且正在努力学习(目前还一知半解,比较菜啊:)。但是有人要用面向过程,我也没办法。毕竟我的水平也说服不了那些人,也没用OOP做过商业项目。

不过个人感觉,用户并不关心你使用什么语言或技术,他只要一个满意的结果。所以呢不管你用什么开发,都要满足用户的需求。原来面向过程的时候,遇到很多问题,不能满足用户需求,或者要花费大量的时间和金钱才能满足用户。所以才提出OO,但OO也不是万能的,也要不断改进和完善。

就目前国内的现状来讲,面向过程的思想方法还根深蒂固,而国内OO大师并不多,真正完全使用OO的公司或团队并不多见吧。大多数人都知道OO好,可真正好在什么地方,如何恰当的使用OO,恐怕还象我这样有些迷糊吧。但不管怎么说,OO是方向。

来了几次Jdon,觉得这是个很不错的地方,想跟大家学习学习,提高自己的水平。


>>OOP其实是便于扩展而不适于修改。原因简单之极,写在一起的改起来只需改一处,分开写的改起来则要改每一处。

我想可扩展和易修改还是要根据具体情况,和系统如何设计来定的,不能一概而论。我用OOP的时候,遇到过为个添加、修改某个功能而改动好几个类的,也遇到过只要改动一个类的情况。但总的来说,要比我用面想过程的时候舒服多了。


>>所以我们搞软件的诸位同道,居于不同的阵营中,不免终日比短较长,其实是没有必要的。各种语言都有他的优势与适用范围。做好产品、服务的市场定位与技术定位,扬长避短才是明智之举。

完全同意楼主的这句话。

OO本身也一直处于发展之中,就拿2001年出的Jive2.0为例子,我推荐它是学习设计模式的sample,Jive2.0完全使用了OO,主要有ForumThread ForumMessage等主要实体对象,设计者将有关ForumMessage的很多操作都放入了该对象中,结果导致该对象异常复杂,再加上权限系统没有和业务系统实现组件分离,这样导致维护拓展Jive2.0非常麻烦,这体现了当初朴素的OOP反而导致系统更不易于维护和拓展,违背了OOP的宗旨。

后来,有了新的对象建模思想,有了领域建模和服务概念,有了AOP以及DI,这样Jive2.0的老问题就得到了很好的解决,这也是我重写JiveJdon3.0的架构基础,更正了以前的老问题。

http://www.jdon.com/jivejdon/thread/32220.html

这是大半年前的体会,当时笔者正处于OOP的进阶阶段。也就是说,一直用OOP,但没有真正领会OOP。

这半年投入了对PHP等函数式编程的实践中,这才真正认识到OOP的好处。函数式编程也可以做到部分封装与重用,但比起OOP,还是困难得多。

最近台阶终于上来了,学会写自己应用中通用的类,学会了扩展已有的Java类库,这才充分体会到OOP对代码质量提高的重大作用。当你真正学会OOP的那天起,才会发觉编程的乐趣无穷。才会发觉通过建构高质量可重用的类库,编程也可以像一棵幼苗长成大树那般轻松、自然、高效。

to lgx522:

php也可以oo的, php4已经支持好多oo特性, php5就更多了

你写php, 也可以完全用oo的思想来写(当然这只是对数据层和业务层来说, 对于表现成, 还是用过程式的方便)。

oo是一种思想, 语言只是工具。

[该贴被alexlee002于2008-02-15 16:11修改过]

有一点意见,那就是数据结构的学习绝不是什么歪曲学生思想。
而是绝对必要的。而且印象中中n wirth对数据结构的定义就是
“数据的逻辑结构和定义在其上的一组运算”。其实已经很像object的定义了。而且数据结构课程主要是培养学生的算法分析和处理能力吧。
不是面向软件工程的课。

而且我觉得写算法的就是比搭架构的值钱,从数量上的分配就看出来了。
有能力搭架构的人很多,而且这种人也比较有固定的培养方法和学习途径。
而算法呢?你知道怎么培养嘛?这种人基本是生出来的不是教出来的。