新聞中心
面向對象在過去的十多年里一直被廣泛的宣傳,現(xiàn)在已經(jīng)成為世所公認的比面向過程更優(yōu)秀的編程模式,但是——過猶不及。Java將被作為面向對象編程語言的典型來做說明,Python將被作為面向過程的語言來說明,雖然Python也面向對象。

公司主營業(yè)務:成都網(wǎng)站建設、成都網(wǎng)站制作、移動網(wǎng)站開發(fā)等業(yè)務。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)公司推出肅寧免費做網(wǎng)站回饋大家。
1、我們需要全局變量和函數(shù)
java作為一個典型的面向對象的編程語言,為什么要設static關鍵字。這從側面說明,面向對象不是***的。我們需要全局性的變量、全局性的函數(shù)(方法)。
單例的設計模式,是試圖用面向對象的方法來做全局性的函數(shù)。因為對象只會被創(chuàng)建一次,那該對象的方法事實上就是一個全局函數(shù)。即便單例可以用面向對象的方法來解決了全局函數(shù)的問題,但要獲取單例的實例,我們依然無法避免使用static變量來hold這個實例,無法避免使用static函數(shù)來獲取這個實例。
2、我們需要Callback函數(shù)
面向過程的語言會有類似這樣的代碼:
- Python代碼
- def some_function(param...)
- //my codes...
- addListener('some_event',some_function)
- def some_function(param...)
- //my codes...
- addListener('some_event',some_function)
而試圖完全對象化的Java語言有一個很尷尬的做法,Java代碼:
- interface MyCallback{
- MyReturenType myCallbackMethod(MyParam param,...);
- }
- class MyCallbackImpl implement MyCallback{
- MyReturenType myCallbackMethod(MyParam param,...){
- //My codes...
- }
- }
- someObj.addListener(new MyCallbackImpl());
- interface MyCallback{
- MyReturenType myCallbackMethod(MyParam param,...);
- }
- class MyCallbackImpl implement MyCallback{
- MyReturenType myCallbackMethod(MyParam param,...){
- //My codes...
- }
- }
- someObj.addListener(new MyCallbackImpl());
我們可以看出,為了這個回調,我們定義了接口,定義了實現(xiàn)類,并且構造了 MyCallbackImpl的對象,并且降低了代碼的可讀性。我見過許多對回調很暈的同學,我想不是他們的理解能力問題,而是面向對象的這種做法本身的問題。
#p#
3、面向對象的代碼在重構和重用上沒有面向過程的靈活
比如這樣的一段代碼,Java代碼:
- class MyClassA{
- TypeA methodA(ParamA){
- //根據(jù)ParamA,this.someField得出返回值
- }
- }
- class MyClassB{
- TypeB methodB(ParamB){
- //根據(jù)ParamA,this.someField得出返回值
- }
- }
- ...
- MyClassA objA = new MyClassA();
- objA.methodA(paramA)
- MyClassB objB = new MyClassB();
- objB.methodB(paramB)
- class MyClassA{
- TypeA methodA(ParamA){
- //根據(jù)ParamA,this.someField得出返回值
- }
- }
- class MyClassB{
- TypeB methodB(ParamB){
- //根據(jù)ParamA,this.someField得出返回值
- }
- }
- ...
- MyClassA objA = new MyClassA();
- objA.methodA(paramA)
- MyClassB objB = new MyClassB();
- objB.methodB(paramB)
methodA只與paramAmethodA被限定在MyClassA的對象中調用,methodB被限定在MyClassB的對象中調用,這兩個方法由于業(yè)務范疇的原因被歸入相應的Class。讓我們來看看這樣的代碼用面向過程的方式會如何寫,Python代碼:
- def methodA(paramA,paramField):
- //根據(jù)ParamA,paramField得出返回值
- def methodB(paramB,paramField):
- //根據(jù)ParamB,paramField得出返回值
- class MyClassA{
- }
- class MyClassB{
- }
- ...
- objA = MyClassA()
- objB = MyClassB()
- methodA(paramA,objA.someField)
- methodB(paramB,objB.someField)
- def methodA(paramA,paramField):
- //根據(jù)ParamA,paramField得出返回值
- def methodB(paramB,paramField):
- //根據(jù)ParamB,paramField得出返回值
- class MyClassA{
- }
- class MyClassB{
- }
- ...
- objA = MyClassA()
- objB = MyClassB()
- methodA(paramA,objA.someField)
- methodB(paramB,objB.someField)
這里的面向過程的代碼中出現(xiàn)了MyClassA和MyClassB,但這兩個類完全是空的,你可以只理解為是一個數(shù)據(jù)結構而已。現(xiàn)在需求發(fā)生了改變,MyClassA需要實現(xiàn)類似methodB的功能,MyClassB要實現(xiàn)類似methodA的功能。我們先看看,面向過程的代碼要做什么修改,Python代碼:
- def methodA(paramA,paramField):
- //根據(jù)ParamA,paramField得出返回值
- def methodB(paramB,paramField):
- //根據(jù)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)
- def methodA(paramA,paramField):
- //根據(jù)ParamA,paramField得出返回值
- def methodB(paramB,paramField):
- //根據(jù)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函數(shù)————本質上是一種面向過程的方式。
#p#
引申:數(shù)據(jù)與邏輯的綁定還是分離?
面向對象編程在代碼邏輯上是意味著什么?個人認為面向對象在代碼邏輯上意味著數(shù)據(jù)與邏輯的綁定。可以想象成 C的Structure和C的function結合成了Cpp的Class。
面向過程在代碼邏輯上意味著什么?個人認為面向過程在代碼邏輯上意味著數(shù)據(jù)與邏輯的分離。
我們經(jīng)常說MVC,數(shù)據(jù)、邏輯、視圖分離。那么我們在最基本的代碼上就不需要這種分離了嗎?程序=數(shù)據(jù)結構+算法,對象也可以理解為數(shù)據(jù)結構和算法的綁定, 對象更加的接近一個程序的完整結構,而過程則更像一個代碼段。從這個角度看,很難說這是優(yōu)點或缺點。
引申:面向對象曾經(jīng)輝煌但已褪色的光輝
面向對象出現(xiàn)之初,還是c語言時代,充滿了無層次結構的函數(shù),面向對象給函數(shù)帶來了歸屬地,讓函數(shù)可以被更好的整理。而如今,面向過程的語言,也可以通過包的概念來整理函數(shù)的歸屬。
此外,OO帶來訪問控制的一些概念,private,protected,public,這些訪問控制的確令人眼前一亮,但很難說他還有吸引力。對于訪問控制,在編譯原理上面向過程的語言同樣可以實現(xiàn),但更重要的還是一個好的編碼習慣,比如python的__前綴函數(shù),開發(fā)者會自然的規(guī)避調用它。
引申:面向對象最有魅力的地方在哪?
個人認為,面向對象***的吸引力在于他的表現(xiàn)力??催@樣一段代碼,Java代碼:
- class Fish{
- void swim(){
- //the fish swimming
- }
- }
- Fish fish=new Fish()
- fish.swim()
- class Fish{
- void swim(){
- //the fish swimming
- }
- }
- Fish fish=new Fish()
- fish.swim()
來看面向過程的實現(xiàn),Python代碼:
- def swim(fish):
- //the fish swimming
- fish = Fish()
- swim(fish)
- def swim(fish):
- //the fish swimming
- fish = Fish()
- swim(fish)
面向對象的代碼,我們很直觀的看到 fish.swim() 是魚游泳。而面向過程的代碼則是 swim(fish),游泳這條魚,函數(shù)定義也許改做 make_fish_swim(fish) 更合適。
尾聲:什么時候用OO,什么時候用PO?
浮在海上的冰山,大部分的內(nèi)容在海面以下。海面以上的用OO來表現(xiàn)會更美,海面以下的用PO來表現(xiàn)會更合適。
新聞名稱:面向對象之弊面向過程之優(yōu)
網(wǎng)站路徑:http://fisionsoft.com.cn/article/dhdeieh.html


咨詢
建站咨詢
