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

面向对象在过去的十多年里一直被广泛的宣传,现在已经成为世所公认的比面向过程更优秀的编程模式,但是——过犹不及。Java将被作为面向对象编程语言的典型来做说明,Python将被作为面向过程的语言来说明,虽然Python也面向对象。

公司主营业务:成都网站建设、成都网站制作、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联公司是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联公司推出肃宁免费做网站回馈大家。

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

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

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

2、我们需要Callback函数

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

 
 
 
  1. Python代码   
  2. def some_function(param...)     
  3.    //my codes...     
  4.     
  5. addListener('some_event',some_function)    
  6. def some_function(param...)  
  7.    //my codes...  
  8. addListener('some_event',some_function) 

而试图完全对象化的Java语言有一个很尴尬的做法,Java代码:

 
 
 
  1. interface MyCallback{     
  2.    MyReturenType myCallbackMethod(MyParam param,...);     
  3. }     
  4. class MyCallbackImpl implement MyCallback{     
  5.    MyReturenType myCallbackMethod(MyParam param,...){     
  6.      //My codes...     
  7.    }     
  8. }     
  9. someObj.addListener(new MyCallbackImpl());    
  10.  
  11. interface MyCallback{  
  12.    MyReturenType myCallbackMethod(MyParam param,...);  
  13. }  
  14. class MyCallbackImpl implement MyCallback{  
  15.    MyReturenType myCallbackMethod(MyParam param,...){  
  16.      //My codes...  
  17.    }  
  18. }  
  19. someObj.addListener(new MyCallbackImpl()); 

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

#p#

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

比如这样的一段代码,Java代码:

 
 
 
  1. class MyClassA{     
  2.   TypeA methodA(ParamA){     
  3.     //根据ParamA,this.someField得出返回值     
  4.   }     
  5. }     
  6.     
  7. class MyClassB{     
  8.   TypeB methodB(ParamB){     
  9.      //根据ParamA,this.someField得出返回值     
  10.   }     
  11. }     
  12. ...     
  13. MyClassA objA = new MyClassA();     
  14. objA.methodA(paramA)     
  15. MyClassB objB = new MyClassB();     
  16. objB.methodB(paramB)    
  17.  
  18. class MyClassA{  
  19.   TypeA methodA(ParamA){  
  20.     //根据ParamA,this.someField得出返回值  
  21.   }  
  22. }  
  23.  
  24. class MyClassB{  
  25.   TypeB methodB(ParamB){  
  26.      //根据ParamA,this.someField得出返回值  
  27.   }  
  28. }  
  29. ...  
  30. MyClassA objA = new MyClassA();  
  31. objA.methodA(paramA)  
  32. MyClassB objB = new MyClassB();  
  33. objB.methodB(paramB) 

methodA只与paramAmethodA被限定在MyClassA的对象中调用,methodB被限定在MyClassB的对象中调用,这两个方法由于业务范畴的原因被归入相应的Class。让我们来看看这样的代码用面向过程的方式会如何写,Python代码:

 
 
 
  1. def methodA(paramA,paramField):     
  2.    //根据ParamA,paramField得出返回值     
  3. def methodB(paramB,paramField):     
  4.    //根据ParamB,paramField得出返回值     
  5.     
  6. class MyClassA{     
  7. }     
  8. class MyClassB{     
  9. }     
  10. ...   
  11.  
  12. objA = MyClassA()     
  13. objB = MyClassB()     
  14. methodA(paramA,objA.someField)     
  15. methodB(paramB,objB.someField)    
  16.  
  17. def methodA(paramA,paramField):  
  18.    //根据ParamA,paramField得出返回值  
  19. def methodB(paramB,paramField):  
  20.    //根据ParamB,paramField得出返回值  
  21.  
  22. class MyClassA{  
  23. }  
  24. class MyClassB{  
  25. }  
  26. ...  
  27. objA = MyClassA()  
  28. objB = MyClassB()  
  29. methodA(paramA,objA.someField)  
  30. methodB(paramB,objB.someField) 

这里的面向过程的代码中出现了MyClassA和MyClassB,但这两个类完全是空的,你可以只理解为是一个数据结构而已。现在需求发生了改变,MyClassA需要实现类似methodB的功能,MyClassB要实现类似methodA的功能。我们先看看,面向过程的代码要做什么修改,Python代码:

 
 
 
  1. def methodA(paramA,paramField):     
  2.    //根据ParamA,paramField得出返回值     
  3. def methodB(paramB,paramField):     
  4.    //根据ParamB,paramField得出返回值     
  5.     
  6. class MyClassA{     
  7. }     
  8. class MyClassB{     
  9. }     
  10. ...     
  11. objA = MyClassA()     
  12. objB = MyClassB()     
  13. methodA(paramA,objA.someField)     
  14. methodB(paramB,objB.someField)     
  15. #增加下面的两句     
  16. methodB(paramA,objA.someField)     
  17. methodA(paramB,objB.someField)    
  18.  
  19. def methodA(paramA,paramField):  
  20.    //根据ParamA,paramField得出返回值  
  21. def methodB(paramB,paramField):  
  22.    //根据ParamB,paramField得出返回值  
  23. class MyClassA{  
  24. }  
  25. class MyClassB{  
  26. }  
  27. ...  
  28. objA = MyClassA()  
  29. objB = MyClassB()  
  30. methodA(paramA,objA.someField)  
  31. methodB(paramB,objB.someField)  
  32. #增加下面的两句  
  33. methodB(paramA,objA.someField)  
  34. methodA(paramB,objB.someField) 

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

#p#

引申:数据与逻辑的绑定还是分离?

面向对象编程在代码逻辑上是意味着什么?个人认为面向对象在代码逻辑上意味着数据与逻辑的绑定。可以想象成 C的Structure和C的function结合成了Cpp的Class。
面向过程在代码逻辑上意味着什么?个人认为面向过程在代码逻辑上意味着数据与逻辑的分离。

我们经常说MVC,数据、逻辑、视图分离。那么我们在最基本的代码上就不需要这种分离了吗?程序=数据结构+算法,对象也可以理解为数据结构和算法的绑定, 对象更加的接近一个程序的完整结构,而过程则更像一个代码段。从这个角度看,很难说这是优点或缺点。

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

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

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

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

个人认为,面向对象***的吸引力在于他的表现力。看这样一段代码,Java代码:

 
 
 
  1. class Fish{     
  2.   void swim(){     
  3.    //the fish swimming     
  4.  }     
  5. }     
  6.     
  7. Fish fish=new Fish()     
  8. fish.swim()    
  9. class Fish{  
  10.   void swim(){  
  11.    //the fish swimming  
  12.  }  
  13. }  
  14. Fish fish=new Fish()  
  15. fish.swim() 

来看面向过程的实现,Python代码:

 
 
 
  1. def swim(fish):     
  2.   //the fish swimming     
  3. fish = Fish()     
  4. swim(fish)    
  5. def swim(fish):  
  6.   //the fish swimming  
  7. fish = Fish()  
  8. swim(fish) 

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

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

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

当前文章:面向对象之弊面向过程之优
文章起源:http://www.mswzjz.cn/qtweb/news23/268623.html

攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能