`

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

阅读更多
加个通道: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.
分享到:
评论
64 楼 liuyupy 2010-07-18  
世界由成千上万种生物组成...
众生物皆由原子分子组成...

信息的交互在大多数情况下以对象的方式来交互更为形象贴切.
但信息的处理必然是面向过程的.
63 楼 lonelybug 2010-07-18  
各位,我有个提议,不知道大家听说过一句话没有,宁和明白人打假,莫和糊涂人说话。

各位,还是找个人去打假把,别在这里浪费时间了。
62 楼 lonelybug 2010-07-18  
subwayline13 写道
jasongreen 写道

真的还在。

很喜欢断章取义啊。我不是希望我的观点一定要别人认可,我是在说JE规则问题,不想被禁声和隐匿。

赞成反对都OK,哥虽不是牛人,但哥也不是新手,哥是不是新手是不以各位同不同意哥的话而改变的。其实哥一直告诉自己自己是个新手————在真正的牛人面前。


首先歪楼,这个我还是赞成楼主的。记得以前有PHP的讨论,本站老大R胖说PHP必须要关闭数据库连接,另一个哥们儿说从来就没关过数据库连接,被众人看成“新手”,后来那个哥们翻出PHP源代码,原来PHP不用关闭数据库连接,请求结束后自动关掉,那个关闭数据库连接的函数是个空实现。

回到主楼,听到了个说法“设计模式是语言表达能力低下的产物”!JAVA是一个相当呆板的语言,不得不用很多设计模式,目前很多语言已经把设计模式加入到语言中了。

我个人认为OO是要体现“做什么”,隐藏“怎么做”,为了能更容易维护和复用,JAVA设计模式是在抗争僵硬的语法,一些JAVA上所谓“经典”的设计模式,在一些灵活的语言中根本用多不到。


嗯,你是该好好看看design patterns原著的开篇介绍了!

好奇问问php那么灵活,请问如何实现singleton设计模式?

最后告诉你,设计模式跟Java没有直接关系,设计模式就是设计模式,就连design patterns这本书中的例子也很好用Java去做。

一帮做外包天天SSH的,发这么多口水帖子干啥,我很奇怪!
61 楼 lonelybug 2010-07-18  
jasongreen 写道
lonelybug 写道
jasongreen 写道
靠,要被新手了~~~,在javaeye想说两句话还真难


是不是新手我不知道也没办法知道,但是,我唯一能确定的是,你的帖子还在,所以,你说话还是说了,而别人的回复也都在,所以,说话的权利都是相同的。

如果,你觉得,你说出来的观点就一定要别人认可,你才算说话,那决我估计,你这辈子能是算说了话的时间不会超过1分钟。


真的还在。

很喜欢断章取义啊。我不是希望我的观点一定要别人认可,我是在说JE规则问题,不想被禁声和隐匿。

赞成反对都OK,哥虽不是牛人,但哥也不是新手,哥是不是新手是不以各位同不同意哥的话而改变的。其实哥一直告诉自己自己是个新手————在真正的牛人面前。



什么叫做“真的还在”?是我理解问题还是你表达问题。

如果怕我断章取义,那你就把东西写在一个帖子里,别这么罗里巴嗦的。
60 楼 carlkkx 2010-07-18  
JE帐号 写道
我被很多人雷到了...
OO是一种认识问题的思想.他与实现技巧没什么关系.所以LZ举的回调函数的注册,包括某楼说的什么GO没有继承之类的,和OO无关.最多是和Java有关.而像有人举的C#的实现,更多的类似语法糖而已.
OO从来不是作为真理出现的,OO仅仅是我们使用程序去映射现实的一个比较好的实践.
所以你去讨论OO,应该是去讨论OO对处理哪些场景有很大帮助,哪些场景下却显得力不从心.而不是揪着个语言,说这不好那不好.


不要小看语法糖,形式会改变你思考问题的方式。
59 楼 JE帐号 2010-07-18  
我被很多人雷到了...
OO是一种认识问题的思想.他与实现技巧没什么关系.所以LZ举的回调函数的注册,包括某楼说的什么GO没有继承之类的,和OO无关.最多是和Java有关.而像有人举的C#的实现,更多的类似语法糖而已.
OO从来不是作为真理出现的,OO仅仅是我们使用程序去映射现实的一个比较好的实践.
所以你去讨论OO,应该是去讨论OO对处理哪些场景有很大帮助,哪些场景下却显得力不从心.而不是揪着个语言,说这不好那不好.

58 楼 mallon 2010-07-18  
关键原因是面向对象得还不够深入,看看JavaScript、Lua等动态语言,“基于对象”而不是“面向对象”,一切都是对象,包括函数,而对象可以任意构建,不再需要“class”等之类的定义了。多完美!
57 楼 jasongreen 2010-07-17  
lonelybug 写道
jasongreen 写道
靠,要被新手了~~~,在javaeye想说两句话还真难


是不是新手我不知道也没办法知道,但是,我唯一能确定的是,你的帖子还在,所以,你说话还是说了,而别人的回复也都在,所以,说话的权利都是相同的。

如果,你觉得,你说出来的观点就一定要别人认可,你才算说话,那决我估计,你这辈子能是算说了话的时间不会超过1分钟。


真的还在。

很喜欢断章取义啊。我不是希望我的观点一定要别人认可,我是在说JE规则问题,不想被禁声和隐匿。

赞成反对都OK,哥虽不是牛人,但哥也不是新手,哥是不是新手是不以各位同不同意哥的话而改变的。其实哥一直告诉自己自己是个新手————在真正的牛人面前。
56 楼 lonelybug 2010-07-17  
jasongreen 写道
靠,要被新手了~~~,在javaeye想说两句话还真难


是不是新手我不知道也没办法知道,但是,我唯一能确定的是,你的帖子还在,所以,你说话还是说了,而别人的回复也都在,所以,说话的权利都是相同的。

如果,你觉得,你说出来的观点就一定要别人认可,你才算说话,那决我估计,你这辈子能是算说了话的时间不会超过1分钟。
55 楼 lonelybug 2010-07-17  
我对LZ也就不再打无聊的口水战了,我只能告诉你一点,你这种思维下去,编成世界的这层窗户纸你能桶破的机会十分渺茫!

54 楼 抛出异常的爱 2010-07-16  
OO是像个人一样说话....
(大多数提到性能那些人说话像台编译器)
并使用一些行业特有名词
当然在企业开发应该会有很大的用处
但被EJB的性能败了家.

如果你们想让别人听懂你推导的数学式证明过程当然可以用OP
但大多数人在说话时使用了大量的语竟信息.
53 楼 ironsabre 2010-07-16  
subwayline13 写道
jasongreen 写道
subwayline13 写道
Magicloud 写道
点了新手帖。
从java来论述OO本身就使得本文成为无价值文章。


赞成,楼主列举的只能是JAVA语言之弊,其他的实用主义的语言,比如C#,解决了很多JAVA的问题,语言都是站在别人肩膀上的,楼主不应该拿相对过时的JAVA语言来论述OO,应该多考察一下别的语言,比如RUBY,C#什么的。


真是对牛弹琴啊,我说的是OO这种编程方式的缺陷,不是说java语言的缺陷。那你们把java代码换成其他代码好了。


如果是换是别的语言,根本就不会是用JAVA那种语法。

button1.Click += delegate(object sender, EventArgs e) { MessageBox.Show("test"); };


用C#的时候还用匿名内部类处理事件吗?JAVA的方式就是OO,其他语言就不OO了,楼主,啥是OO,你搞清楚了吗?


你告诉我,什么是oo好不好?
52 楼 csdxqzp 2010-07-16  
一看就是出来丢逼的!
51 楼 flasheep 2010-07-16  
不敢苟同啊
50 楼 jasongreen 2010-07-16  
subwayline13 写道
Magicloud 写道
点了新手帖。
从java来论述OO本身就使得本文成为无价值文章。


赞成,楼主列举的只能是JAVA语言之弊,其他的实用主义的语言,比如C#,解决了很多JAVA的问题,语言都是站在别人肩膀上的,楼主不应该拿相对过时的JAVA语言来论述OO,应该多考察一下别的语言,比如RUBY,C#什么的。


真是对牛弹琴啊,我说的是OO这种编程方式的缺陷,不是说java语言的缺陷。那你们把java代码换成其他代码好了。
49 楼 tuti 2010-07-16  
先去读了 SICP 再回来说事吧。

http://book.douban.com/subject/1148282/
48 楼 ironsabre 2010-07-16  
Magicloud 写道
点了新手帖。
从java来论述OO本身就使得本文成为无价值文章。


你来个有价值的文章我看看。
47 楼 ironsabre 2010-07-16  
jasongreen 写道
靠,要被新手了~~~,在javaeye想说两句话还真难


我绝对不能算是新手贴,我点了良好。
46 楼 Magicloud 2010-07-16  
点了新手帖。
从java来论述OO本身就使得本文成为无价值文章。
45 楼 llade 2010-07-16  
引用


怎么看都是在痛批C++不能精确处理内核的事情。

相关推荐

Global site tag (gtag.js) - Google Analytics