`

面向对象之弊,面向过程之优

阅读更多
加个通道:G A E - R P R O X Y, http://www.iteye.com/topic/717232

没想到写了这么多。本文并不是要否定OO,而是要给PO更多的肯定。这篇文字不像想象中那么长,只是些一看便知的代码占了些篇幅,请大家花3分钟看完,这将会是个很有意义的讨论。为了方便大家阅读,我把提纲先列在上面。
1。 我们需要全局变量和函数。
2。 我们需要Callback函数。
3。面向对象的代码在重构和重用上没有面向过程的灵活
引申:数据与逻辑的绑定还是分离?
引申:面向对象曾经辉煌但已褪色的光辉
引申:面向对象最有魅力的地方在哪?
尾声:什么时候用OO,什么时候用PO?

回复ray_linn的C#代码:
http://www.iteye.com/topic/712942?page=2#1580812
---------------------
面向对象在过去的十多年里一直被广泛的宣传,现在已经成为世所公认的比面向过程更优秀的编程模式,但是——过犹不及。

[del]Java将被作为面向对象编程语言的典型来做说明,Python将被作为面向过程的语言来说明,虽然Python也面向对象。[/del]
有人说我是在说Java语言的问题,而不是说OO的问题,所以我把OO的代码也改成了python实现。


1。 我们需要全局变量和函数。

java作为一个典型的面向对象的编程语言,为什么要设static关键字。这从侧面说明,面向对象不是万能的。我们需要全局性的变量、全局性的函数(方法)。

单例的设计模式,是试图用面向对象的方法来做全局性的函数。因为对象只会被创建一次,那该对象的方法事实上就是一个全局函数。即便单例可以用面向对象的方法来解决了全局函数的问题,但要获取单例的实例,我们依然无法避免使用static变量来hold这个实例,无法避免使用static函数来获取这个实例。

2。 我们需要Callback函数。

面向过程的语言会有类似这样的代码:

def some_function(param...)
   //my codes...

addListener('some_event',some_function)

而试图完全对象化的Java语言有一个很尴尬的做法
class MyCallbackImpl:
   def myCallbackMethod(MyParam param,...):
     //My codes...

someObj.addListener('some_event',MyCallbackImpl());

我们可以看出,为了这个回调,我们定义了接口,定义了实现类,并且构造了 MyCallbackImpl的对象,并且降低了代码的可读性。我见过许多对回调很晕的同学,我想不是他们的理解能力问题,而是面向对象的这种做法本身的问题。

3。面向对象的代码在重构和重用上没有面向过程的灵活

比如这样的一段代码:
class MyClassA:
  def methodA(self,ParamA){
    //根据ParamA,this.someField得出返回值

class MyClassB:
  def methodB(self,ParamB):
     //根据ParamA,this.someField得出返回值
...
objA = MyClassA();
objA.methodA(paramA)
objB = MyClassB();
objB.methodB(paramB)


methodA只与paramAmethodA被限定在MyClassA的对象中调用,methodB被限定在MyClassB的对象中调用,这两个方法由于业务范畴的原因被归入相应的Class。让我们来看看这样的代码用面向过程的方式会如何写:
def methodA(paramA,paramField):
   //根据ParamA,paramField得出返回值
def methodB(paramB,paramField):
   //根据ParamB,paramField得出返回值

class MyClassA:
  #..
class MyClassB:
  #..
...
objA = MyClassA()
objB = MyClassB()
methodA(paramA,objA.someField)
methodB(paramB,objB.someField)

这里的面向过程的代码中出现了MyClassA和MyClassB,但这两个类完全是空的,你可以只理解为是一个数据结构而已。

现在需求发生了改变,MyClassA需要实现类似methodB的功能,MyClassB要实现类似methodA的功能。
我们先看看,面向过程的代码要做什么修改:
def methodA(paramA,paramField):
   //根据ParamA,paramField得出返回值
def methodB(paramB,paramField):
   //根据ParamB,paramField得出返回值

class MyClassA:
  #..
class MyClassB:
  #..
...
objA = MyClassA()
objB = MyClassB()
methodA(paramA,objA.someField)
methodB(paramB,objB.someField)
#增加下面的两句
methodB(paramA,objA.someField)
methodA(paramB,objB.someField)

可是面向对象的代码呢?等待他的将是代码的重构,也许他可以选择的重构方式是static函数————本质上是一种面向过程的方式。

==================================================================

引申:数据与逻辑的绑定还是分离?
面向对象编程在代码逻辑上是意味着什么?个人认为面向对象在代码逻辑上意味着数据与逻辑的绑定。可以想象成 C的Structure和C的function结合成了Cpp的Class。
面向过程在代码逻辑上意味着什么?个人认为面向过程在代码逻辑上意味着数据与逻辑的分离。
我们经常说MVC,数据、逻辑、视图分离。那么我们在最基本的代码上就不需要这种分离了吗?
程序=数据结构+算法 ,对象也可以理解为数据结构和算法的绑定, 对象更加的接近一个程序的完整结构,而过程则更像一个代码段。
从这个角度看,很难说这是优点或缺点。

引申:面向对象曾经辉煌但已褪色的光辉

面向对象出现之初,还是c语言时代,充满了无层次结构的函数,面向对象给函数带来了归属地,让函数可以被更好的整理。而如今,面向过程的语言,也可以通过包的概念来整理函数的归属。

此外,OO带来访问控制的一些概念,private,protected,public,这些访问控制的确令人眼前一亮,但很难说他还有吸引力。对于访问控制,在编译原理上面向过程的语言同样可以实现,但更重要的还是一个好的编码习惯,比如python的 __ 前缀函数,开发者会自然的规避调用它。

引申:面向对象最有魅力的地方在哪?

个人认为,面向对象最大的吸引力在于他的表现力。看这样一段代码:
class Fish{
  def swim(){
   //the fish swimming

fish=Fish()
fish.swim()

来看面向过程的实现
def swim(fish):
  //the fish swimming

fish = Fish()
swim(fish)

面向对象的代码,我们很直观的看到 fish.swim() 是鱼游泳。而面向过程的代码则是 swim(fish),游泳这条鱼,函数定义也许改做 make_fish_swim(fish) 更合适。

尾声:什么时候用OO,什么时候用PO?

浮在海上的冰山,大部分的内容在海面以下。海面以上的用OO来表现会更美,海面以下的用PO来表现会更合适。

Use OO as data-structure more than design patterns, more static utility functions.
分享到:
评论
104 楼 lliiqiang 2010-11-10  
对于回调函数问题我觉得java应该许可定义函数类型变量,就像数组一样.指定某个参数类型和返回值类型的函数,当然这里会涉及到动态覆盖.以及关键字注明是否可以回调
103 楼 ppgunjack 2010-08-12  
"C++最早是 c with class。后期引入了template 等概念。严格来说不具有完整oop的特性"
除了依赖根对象和反射的设计,我想不出有什么框架是java能做,c++做不了的或者很难做的。
即使反射,c++某些库也有自己的实现,只是没在整体的语言层面形成标准
c++的面向oo的语法相比java只多不少,不知道这句是从何而来
java某个层面可以说是c++在面向对象领域的改良版,也同样可说成是精简版,引入的不多,削减的不少
java在库的可用性和丰富程度和进步速度,不是c++可比的,毕竟java在语言层面不用纠结于移植和标准之争。

hatedance 写道

1 关于“终端-主机转到cs又回到类似终端-主机的bs架构”这个问题,我觉得是当年最初为了利用大型主机的资源,后来是c/s是因为没了大型主机,也没有浏览器这样的标准客户端,再后来b/s是为了方便发布.客户端的胖瘦会一直演变下去。

2 你的职责还是属于你的,你的manager不会替你干活,他下指令给你让你干活。如果你只是个不会干活的参数(headcount),他估计早就废了你。

b/s已经不仅仅是发布这么简单了
终端-主机的时代是因为终端根本做不了事
cs时代是因为希望终端多做事,主机资源太珍贵
b/s时代是因为主机资源不再珍贵,且功能更强大,体系结构能更简单。原因就是manager承担更多的事务
看看现在针对应用服务的云google app
针对你的职责,你得弄清楚到底什么是你的职责
假设A,B,C,你是A
C需要你和B的输出,但你不需要C和B的任何资源,那你希望自己去了解C了解B吗(import c;import b),你愿意主动push B然后向C去输出吗(c=a.plus(b); )?你可以这样做,但是这样多半会导致职责不明和混乱
最合理的做法当然是要么C驱动你和B,要么找个manager去协调A,B,C
102 楼 mathgl 2010-08-12  
ppgunjack 写道
liudun 写道
我想多看看优秀的开源代码是有益于理解OOP的。

工作中接触的同事们,很多都有搞C、C++经历的,所以它们写的java代码都是贫血对象——就是说领域对象本省总是没有任何逻辑,逻辑都放到**Manager、**Service里面去了。这没办法,‘一切皆对象’的思想并没有普及。到处都是面向过程的java代码。

我是电信行业的,有个网管规范叫TMF814,针对专属网的corba接口定义。
这个接口的设计特点就是典型的“所以它们写的java代码都是贫血对象——就是说领域对象本省总是没有任何逻辑,逻辑都放到**Manager、**Service里面去了”。而制定这些标准的都是牛人,不是没深刻理解面向对象思想的人。
我编写网管软件,一开始对象模型采取兼容814的corba对象,同时将相当于部分Manager,Service的逻辑归入到领域对象,但随着越往后写越觉得规范定义的方式是合理的。领域对象承载了过多的逻辑,引入了过度对其他对象的引用,领域对象的膨胀发觉时及其危险的,很容易就带来代码的不可控和难以重构。
举例来说对象A,B,C在作为设备对象存储设备信息,一种情况下,需要获得一个List<C>,而这个List<C>是由List<A>和List<B>共同决定的,这种情况下引入Manager、和Service对象就是顺理成章的事情了

设备对象A,B,C往往是相互关联相互作用的,而网管里面同时涉及大量这种互相关联的逻辑,最好的方式还是应该都放入领域对象之外的控制逻辑中,就成了Manager、和Service对象,而看看Manager、和Service对象其实严格意义是说白了就是PO函数的作用域封装。

实际工作中感觉OO解决的主要问题集中在几个方面:
1.接口契约
2.如楼主所说的作用域的划定和封装
3.RTTI,这个已经不是严格意义上属于OO语言层面的内容,但越偏向OO的语言,这个东西作用范围越大。JAVA几乎所有的流行框架实际都是建立在这个基础之上的。不过我是觉得这个是可读和调试的天敌,用编码的复杂性带来了运行时的灵活性。但同时也将问题从编译器带到了运行期。C++在RTTI方面是先天不良,没有标准,C++只能各显神通的人肉级别做RTTI比如MFC,不是因为这个相信java的很多框架设计思想是很容易复制到c++的。RTTI大大简化了分布式的实现,这也是java在应用广度上能超越c++的重要原因

OO感觉还是适合主要放在初期的领域模型设计当中,并且对于抽象和继承尤其要谨慎,现在发觉不合理的代码抽象远比代码冗余危险,后者顶多带来重构困难,前者基本上让你抓狂到有推到重写的冲动。

至于所谓的面向对象更接近人的思维模式和面向对象更适合解决复杂问题,觉得有点扯
人的思维永远是基于语言的,学的汉语就是汉语思维,英文就是英文思维,但不管什么思维,描述一个问题语法都是主谓宾,定状定补,这就是典型的面向过程的思维。
至于面向对象更适合解决复杂问题,确切的说应该是面向对象更适合解决庞杂的问题,将业务模型和实现逻辑拆分化整为零。实际面向过程同样有这个能力,只是天然的缺乏多态继承的全面向过程语言要做很多额外的工作,拆分成本要高很多,并且封装性和作用域也很难保证。
谈到复杂性世界上能有多少软件面向的业务能比操作系统或者类似ORACLE的CBO更复杂。


C++最早是 c with class。后期引入了template 等概念。严格来说不具有完整oop的特性。java的设计也不能照搬到cpp上去。

现在我手头的项目,数据的定义通过ice来制定,server 用cpp ,client用 其他语言。ice制定的其实就是所谓的规范。这种复合的环境下,使用贫血对象是合理的。
101 楼 hatedance 2010-08-12  
ppgunjack 写道
依赖很麻烦,甚至可以说是一切麻烦的根源,数据库范式解决的就是依赖,接口解决的还是依赖
你说cs好还是bs好,哪个容易维护
计算机从最早的终端-主机转到cs又回到类似终端-主机的bs架构

你认为plus是class A的职责吗,如果是放进去ok,不是就不应该放

人就是人,人自己能干活
但你可以看看自己干的多少活不是别人让你干的,也只是作为个参数而已被manager在处理


1 关于“终端-主机转到cs又回到类似终端-主机的bs架构”这个问题,我觉得是当年最初为了利用大型主机的资源,后来是c/s是因为没了大型主机,也没有浏览器这样的标准客户端,再后来b/s是为了方便发布.客户端的胖瘦会一直演变下去。

2 你的职责还是属于你的,你的manager不会替你干活,他下指令给你让你干活。如果你只是个不会干活的参数(headcount),他估计早就废了你。
100 楼 ppgunjack 2010-08-10  
依赖很麻烦,甚至可以说是一切麻烦的根源,数据库范式解决的就是依赖,接口解决的还是依赖
你说cs好还是bs好,哪个容易维护
计算机从最早的终端-主机转到cs又回到类似终端-主机的bs架构

你认为plus是class A的职责吗,如果是放进去ok,不是就不应该放

人就是人,人自己能干活
但你可以看看自己干的多少活不是别人让你干的,也只是作为个参数而已被manager在处理
99 楼 tedeyang 2010-08-10  
ppgunjack 写道
有意思的是,我在写代码的时候,真的最早就是按照c=a.plus(b);来写的
大概的样子是
A a;
B b;
C c;
c=a.parse(b)
类似这个样子,不过越往后,越觉得不合理,就演变变成了
c=Parser.parse(a,b),
代码一半是前面的实现,一半是后面的实现,很滑稽
其实思路很容易理解:
1.a需要知道b吗,不需要我干嘛要A的class引入B。
2.c需要知道a或者b嘛,可以说需要可以说不需要。那么只有两条路:A,B作为构造参数或者第三方处理,当c是个list或者不是自己能控制代码的类的时候,结果就已经很明确了,路只有一条

建议看看ruby是怎么做加法的。

另外,职责分散了好做,还是把职责统一到一个Manager里好维护?
仅仅ABC三个类就有8种相加的组合,如果是10个类呢?你的Manager准备写多少逻辑?是指数级别的吧。
相反,如果各自来处理加法,则A只要处理:加A、加B、加C三种逻辑,是线性的。每个类自己负责自己的事,世界才有规律。
扯远一点,就是大-中-央-集-权好,还是社会自治好。
98 楼 ppgunjack 2010-08-10  
有意思的是,我在写代码的时候,真的最早就是按照c=a.plus(b);来写的
大概的样子是
A a;
B b;
C c;
c=a.parse(b)
类似这个样子,不过越往后,越觉得不合理,就演变变成了
c=Parser.parse(a,b),
代码一半是前面的实现,一半是后面的实现,很滑稽
其实思路很容易理解:
1.a需要知道b吗,不需要我干嘛要A的class引入B。
2.c需要知道a或者b嘛,可以说需要可以说不需要。那么只有两条路:A,B作为构造参数或者第三方处理,当c是个list或者不是自己能控制代码的类的时候,结果就已经很明确了,路只有一条
97 楼 ppgunjack 2010-08-10  
不是参数是贫血对象,而是领域模型是贫血对象,主控逻辑所在的对象则主要是方法包装
两端的版本都是由idl决定的,是不需要其他方式的控制
本来现实世界很多问题并不适合OO。
STL的算法的设计理念就是典型的例子,
不是设备信息用list来表示,而是设备集合信息用list表示。这个list再封装成一个对象没啥意义,这种应用其实可以参考STL。目的就是要集合B和集合C通过运算生成集合A。
cpp放弃rtti是先天缺陷,不是性能,它是静态语言且不是托管语言,没有在语言层面支持,在哪个没标准的年代更没可能依靠宏或者库统一rtti的实现


如果是非贫血对象要做加法就是:c=a.plus(b);
如果是贫血对象就是:c=IntegerManager.plus(a,b);

这个例子的结论我认为正好相反,我有两个问题:
1.plus为何要属于Integer对象。如果今后的逻辑我需要引入更多的计算方法是否应该重构Integer,java的编译方式我不太确定,但如果是c++则不论你是否引入接口,则至少必然导致所有使用Integer头文件的代码都要重编译
2.Integer对象作为数据容器对象,引入了其对象本身,这个还没彰显问题。假设a,b如果是不同class呢?
a所属的class毫无疑问被b给侵入了。那么考虑c=IntegerManager.plus(a,b);其实IntegerManager承接了a和b的桥梁,把关联依赖集中放在了IntegerManager里面。
你觉得处理这个问题的话那种方式更好?
其实table A, table B, table relationAB就是这种模式
其实包括工厂模式和spring作为组件粘合剂我觉得他们更多的思维本质还是是面向过程的只是用xml和接口给美化了而让人忽略了
而且java这样的实际面向过程的工具类少吗,毕竟有些问题只适合这么处理
96 楼 hatedance 2010-08-09  
ppgunjack 写道
liudun 写道
我想多看看优秀的开源代码是有益于理解OOP的。

工作中接触的同事们,很多都有搞C、C++经历的,所以它们写的java代码都是贫血对象——就是说领域对象本省总是没有任何逻辑,逻辑都放到**Manager、**Service里面去了。这没办法,‘一切皆对象’的思想并没有普及。到处都是面向过程的java代码。

我是电信行业的,有个网管规范叫TMF814,针对专属网的corba接口定义。
这个接口的设计特点就是典型的“所以它们写的java代码都是贫血对象——就是说领域对象本省总是没有任何逻辑,逻辑都放到**Manager、**Service里面去了”。而制定这些标准的都是牛人,不是没深刻理解面向对象思想的人。
我编写网管软件,一开始对象模型采取兼容814的corba对象,同时将相当于部分Manager,Service的逻辑归入到领域对象,但随着越往后写越觉得规范定义的方式是合理的。领域对象承载了过多的逻辑,引入了过度对其他对象的引用,领域对象的膨胀发觉时及其危险的,很容易就带来代码的不可控和难以重构。
举例来说对象A,B,C在作为设备对象存储设备信息,一种情况下,需要获得一个List<C>,而这个List<C>是由List<A>和List<B>共同决定的,这种情况下引入Manager、和Service对象就是顺理成章的事情了

设备对象A,B,C往往是相互关联相互作用的,而网管里面同时涉及大量这种互相关联的逻辑,最好的方式还是应该都放入领域对象之外的控制逻辑中,就成了Manager、和Service对象,而看看Manager、和Service对象其实严格意义是说白了就是PO函数的作用域封装。

实际工作中感觉OO解决的主要问题集中在几个方面:
1.接口契约
2.如楼主所说的作用域的划定和封装
3.RTTI,这个已经不是严格意义上属于OO语言层面的内容,但越偏向OO的语言,这个东西作用范围越大。JAVA几乎所有的流行框架实际都是建立在这个基础之上的。不过我是觉得这个是可读和调试的天敌,用编码的复杂性带来了运行时的灵活性。但同时也将问题从编译器带到了运行期。C++在RTTI方面是先天不良,没有标准,C++只能各显神通的人肉级别做RTTI比如MFC,不是因为这个相信java的很多框架设计思想是很容易复制到c++的。RTTI大大简化了分布式的实现,这也是java在应用广度上能超越c++的重要原因

OO感觉还是适合主要放在初期的领域模型设计当中,并且对于抽象和继承尤其要谨慎,现在发觉不合理的代码抽象远比代码冗余危险,后者顶多带来重构困难,前者基本上让你抓狂到有推到重写的冲动。

至于所谓的面向对象更接近人的思维模式和面向对象更适合解决复杂问题,觉得有点扯
人的思维永远是基于语言的,学的汉语就是汉语思维,英文就是英文思维,但不管什么思维,描述一个问题语法都是主谓宾,定状定补,这就是典型的面向过程的思维。
至于面向对象更适合解决复杂问题,确切的说应该是面向对象更适合解决庞杂的问题,将业务模型和实现逻辑拆分化整为零。实际面向过程同样有这个能力,只是天然的缺乏多态继承的全面向过程语言要做很多额外的工作,拆分成本要高很多,并且封装性和作用域也很难保证。
谈到复杂性世界上能有多少软件面向的业务能比操作系统或者类似ORACLE的CBO更复杂。


1. corba是远程调用。其中的参数应该是贫血对象。因为远程主机上的代码版本有时不是你能控制的。
2. 设备信息用list来表示,就不太OO了。不定义个实体对象,也至少用Map啊。
3. cpp放弃rtti也许是为了性能考虑。因为如果失去这一点,cpp的竞争力大大减弱。cpp是想既要有c的性能,又有oo语言的特性。
4. cbo是否复杂我不知道。但做同样一个产品,分别选用cpp和其他语言实现就能比较出结论了。
5. 很多人反对OO其实是没掌握好OO。
比如,举个例子。Integer对象。那么Integer a=1,b=2;
如果是非贫血对象要做加法就是:c=a.plus(b);
如果是贫血对象就是:c=IntegerManager.plus(a,b);
哪个好是显而易见的。如果你支持PO,那么基本上就选择了static关键词。
问题是在涉及数据库/分布式/并发的现实环境下,要进行ddd就不是这么简单了。
95 楼 ppgunjack 2010-08-07  
liudun 写道
我想多看看优秀的开源代码是有益于理解OOP的。

工作中接触的同事们,很多都有搞C、C++经历的,所以它们写的java代码都是贫血对象——就是说领域对象本省总是没有任何逻辑,逻辑都放到**Manager、**Service里面去了。这没办法,‘一切皆对象’的思想并没有普及。到处都是面向过程的java代码。

我是电信行业的,有个网管规范叫TMF814,针对专属网的corba接口定义。
这个接口的设计特点就是典型的“所以它们写的java代码都是贫血对象——就是说领域对象本省总是没有任何逻辑,逻辑都放到**Manager、**Service里面去了”。而制定这些标准的都是牛人,不是没深刻理解面向对象思想的人。
我编写网管软件,一开始对象模型采取兼容814的corba对象,同时将相当于部分Manager,Service的逻辑归入到领域对象,但随着越往后写越觉得规范定义的方式是合理的。领域对象承载了过多的逻辑,引入了过度对其他对象的引用,领域对象的膨胀发觉时及其危险的,很容易就带来代码的不可控和难以重构。
举例来说对象A,B,C在作为设备对象存储设备信息,一种情况下,需要获得一个List<C>,而这个List<C>是由List<A>和List<B>共同决定的,这种情况下引入Manager、和Service对象就是顺理成章的事情了

设备对象A,B,C往往是相互关联相互作用的,而网管里面同时涉及大量这种互相关联的逻辑,最好的方式还是应该都放入领域对象之外的控制逻辑中,就成了Manager、和Service对象,而看看Manager、和Service对象其实严格意义是说白了就是PO函数的作用域封装。

实际工作中感觉OO解决的主要问题集中在几个方面:
1.接口契约
2.如楼主所说的作用域的划定和封装
3.RTTI,这个已经不是严格意义上属于OO语言层面的内容,但越偏向OO的语言,这个东西作用范围越大。JAVA几乎所有的流行框架实际都是建立在这个基础之上的。不过我是觉得这个是可读和调试的天敌,用编码的复杂性带来了运行时的灵活性。但同时也将问题从编译器带到了运行期。C++在RTTI方面是先天不良,没有标准,C++只能各显神通的人肉级别做RTTI比如MFC,不是因为这个相信java的很多框架设计思想是很容易复制到c++的。RTTI大大简化了分布式的实现,这也是java在应用广度上能超越c++的重要原因

OO感觉还是适合主要放在初期的领域模型设计当中,并且对于抽象和继承尤其要谨慎,现在发觉不合理的代码抽象远比代码冗余危险,后者顶多带来重构困难,前者基本上让你抓狂到有推到重写的冲动。

至于所谓的面向对象更接近人的思维模式和面向对象更适合解决复杂问题,觉得有点扯
人的思维永远是基于语言的,学的汉语就是汉语思维,英文就是英文思维,但不管什么思维,描述一个问题语法都是主谓宾,定状定补,这就是典型的面向过程的思维。
至于面向对象更适合解决复杂问题,确切的说应该是面向对象更适合解决庞杂的问题,将业务模型和实现逻辑拆分化整为零。实际面向过程同样有这个能力,只是天然的缺乏多态继承的全面向过程语言要做很多额外的工作,拆分成本要高很多,并且封装性和作用域也很难保证。
谈到复杂性世界上能有多少软件面向的业务能比操作系统或者类似ORACLE的CBO更复杂。
94 楼 Crusader 2010-08-06  
各有优缺点吧

个人认为面向对象相对于面向过程的最大优点在于更大限度的代码复用

而面向过程相对于面向对象的最大优点在于节省空间和时间
93 楼 lordheart 2010-08-06  
面向对象本来就没考虑到代码量,他是个设计和思路的问题。思路是面向对象的,怎么写都无所谓,思路是面向过程的,怎么的都是面向过程的。楼主的认识也它浮浅了啊。

数据和算法可以玻璃,思路和代码实现也是可以剥离的啊。
92 楼 hannyu 2010-07-30  
我猜楼主没学过设计模式吧?
91 楼 madbluesky 2010-07-28  
前面有个哥们说的好,c语言也能面向对象编程的。所以面向对象是一种思想。

我还记得有谁说过面向对象最大的问题是对过程不够关注,而很多时候过程却是最重要的,比如银行转账的问题。转账的过程是重要的,可面向对象大概会只描述2个用户而已。面向过程,面向对象各有优劣.如果一个问题你觉得使用面向过程的方式更清晰更容易理解那就面向过程好了,而如果觉得使用面向对象的方式更合适那就面向对象好了。

帖子的标题没错,可是lz当从语法角度分析从而得出结论个人感觉太过浅了,因而难以产生认同感。
90 楼 aiyanbo 2010-07-28  
我们也不能一棒子给打死... 各有各的特点和优点...  利用他们的优势来写我们的程序才是最重要的。。。
89 楼 fengfeng925 2010-07-27  
    个人觉得OO更适合做业务层面的东西,也许在开发的过程中没有用PO那么畅快,但是比较两种观念的优劣具体的代码是比较不出来的。
     用PO,写代码流畅,但是程序里大量充斥了全局函数和变量,第一这些变量没有归属感,再加上有的人不爱写注释,所以当重构系统或者重新开发新功能的时候,问题就全部都暴露出来了,因为你不知道哪些全局函数和变量再哪里被调用过,牵一发而动全身,所以只能放任不管,重构也就没什么真实意义可言。(尤其是大系统)。这种情况下,如果要大改动的话,只能推翻重做。
    用OO,因为有了类和继承,接口的概念,所以,可以把共性的东西,抽象出来或者放在父接口或类中,而子接口和实现只需要加上个性的东西就可以。重构上我觉得更加方便些,而且再通用一些的话,完全可以封装出来拿到多个系统之间共享。可以在一定程度上达到系统的最大程度上的重用。
    当然我不否认有的PO大牛水平很高,写的代码重构起来很方便,而有的OO程序员写的代码一样很混乱,给重构造车了重重困难,比较的前提是必须抛开程序员水平之间的良莠不齐。
    比较具体的代码没有多大的意义,不过楼主的观念是好的,有思考,大家才有进步。
   
88 楼 piao_bo_yi 2010-07-27  
每种语言模式都有它的适用范围,LZ大概也是想表达这样一种意思。单纯说谁厉害,的确没啥意义。
OO优势在于多态、类型约定(毕竟大部分采用静态类型系统)、精细可见性来提供出色的封装和重用性。可以认为,OO的表达能力、封装、重用性胜于OP。
缺点:1.但是由于静态类型系统带来的好处,编译时刻就已经确定是否误用类型之间的约定,所以有时候开发人员会过分信赖编译系统而不开发自己的测试架构。(当然,你很难完全把责任推给他,但是当你饿的时候,面前放着美食(比如KFC-unhealthy),和你必须去很远的地方吃健康食品,KFC难免对你造成致命的诱惑)。2.大型项目,组件约定是经常变的,这就要求使用者经常改变约定,由于这些问题,OO有时会过分复杂和冗长。我们项目写了700个类,管理其交互的确不是一件容易的事。
3.另外,我认为最致命的东西在于OO的简化性,这本身就是双刃剑,苦思其解会带来训练有素的头脑,太简单的表述事物有时候会造成白痴的泛滥,这真是一种不好说的特点。
87 楼 拥抱变化之美 2010-07-26  
面向对象的基本特征:封装、继承、多态,它强调的是交互的实体是什么;
面向过程的基本特征:顺序、选择、循环,它强调的是交互的流程走向是什么;

所以没有孰优孰劣之分,只有适用范围之异。
86 楼 docong 2010-07-23  
楼主最大的问题是把java和面向对象混为一谈了。你说的问题,和面向对象有什么关系?
85 楼 522656914 2010-07-21  
用算数和方程解决问题你觉得哪个更直接一些?哪个又更好理解一些呢?
OO是解决问题的一种思想,他带给系统更好的扩展性。
面向过程里面有设计模式么?
个人感觉两者的区别是思考问题解决问题的思路不一样而已

相关推荐

Global site tag (gtag.js) - Google Analytics