“面向對象"和"面向過程"到底有什么區別?



鏈接:http://www.zhihu.com/question/27468564/answer/101951302

當軟件還非常簡單的時候,我們只需要面向過程編程:

定義函數
函數一
函數二
函數三
函數四

定義數據
數據一
數據二
數據三
數據四

最后
各種函數,數據的操作。

當軟件發展起來后,我們的軟件變得越來越大,代碼量越來越多,復雜度遠超Hello World的時候,我們的編寫就有麻煩了:

函數和數據會定義得非常多,面臨兩個問題。

首先是命名沖突,英文單詞也就那么幾個,可能寫着寫着取名時就沒合適的短詞用了,為了避免沖突,只能把函數名取得越來越長。

然后是代碼重復,比如你做一個計算器程序,你的函數就要確保處理的是合理的數據,這樣最起碼加減乘除四個函數里,你就都要寫對參數進行檢測的代碼,寫四遍或者復制粘貼四遍不會很煩,但多了你就痛苦了,而且因為這些檢測代碼是跟你的加減乘除函數的本意是無關的,卻一定要寫在那里,使代碼變得不好閱讀,意圖模糊。

就算一個網絡小說的作者,他每次寫新章節時也不大可能直接打開包含着前面幾百章文字的文檔接着寫。更正常的做法是新建一個文檔,寫新的一章,為的是減小復雜性,減少干擾。更何況代碼那么復雜那么容易出錯的東西。

隨着軟件業的發展,解決辦法就要出來了。

代碼重復,我們可以用函數里面調用函數的方法,比如把檢測代碼抽出來成一個獨立函數,然后加減乘除四個函數運行時只要調用一下檢測函數對參數進行檢查就可以了。分布在四個函數里的重復代碼變成了一個函數,是不是好維護多了。

命名沖突,我們就把這一堆函數們進行分類吧。

比如沒有分類時候,我們取名只能取名:

檢測
整數加
整數減
整數乘
整數除
復數加
復數減
復數乘
復數除
小數加
...

進行歸類后

整數 {
檢測




}
復數 {
檢測




}
小數 {
檢測




}
分數 {
檢測




}

是不是一種叫做類的概念就呼之欲出了,這樣我們打開一個整數類代碼文件,里面就是簡簡單單的加減乘除四個函數,簡單清晰而不會跟外面的其他加減乘除函數命名沖突。

當然,進行歸類后,又有各種的問題和解決辦法了,比如四個類中的檢測也是應該提取出來的,所以簡單的起因最終發展出什么繼承衍生之類挺復雜的一套編程模式。然后學術界那幫人就又亂起什么高大上的名字了,所謂面向對象程序設計去禍害大學里那幫孩子。

就算未來出來一個什么新的面向XX編程,我們也不用多想為什么會出現,肯定是為了解決麻煩而已。

2016年5月23日更新:

上面進行歸類后,代碼其實還是不好維護的,然后我們就繼續提取為:

數 {
檢測




}

整數 {
沿用上面數的設計
}

小數 {
沿用上面數的設計
}

所謂繼承,就是數這個類的整體設計,沿用給整數,分數小數這些類,作為他們的編寫大綱去編寫加減乘除這些函數的具體代碼。根據整數,分數,小數各自的性質,做出各自的調整。

這時數這個類,如果你給它里面的加減乘除函數的寫了一些很粗糙簡單的代碼,就叫做父類,基礎類。子類們“繼承”了父類(把代碼進行了復雜化)。

如果沒寫,那這個類其實就只是個設計圖,叫做抽象類。子類們“實現”了抽象類(把空空的設計變成了具體代碼)。

模版是什么?像C++這種復雜成狗的語言是強類型的,就是給變量進行了類型區分的,比如整數類型,雙整數類型。很明顯這兩種變量所能容納的數據體積是不一樣的,單個函數不能通吃多種類型的參數,我們就可能會面臨下面兩套代碼並存的局面。

單整數類 {
單整數加
單整數減
單整數乘
單整數除
}

雙整數類 {
雙整數加
雙整數減
雙整數乘
雙整數除
}

所以C艹跟其他強類型語言為我們提供了一個所謂模版功能:

<變量類型>整數 {
<變量類型>加
<變量類型>減
<變量類型>乘
<變量類型>除
}

整數類等於把變量類型設置為整數,套上模版
雙整數類等於把變量類型設置為雙整數,套上模版

這樣就寫了一份代碼,得到了兩份類的代碼。

當然,弱類型的編程語言,比如JavaScript或者PHP是沒有這種煩惱的,因為變量沒有類型之分。但變量類型有時候還是很重要的,弱類型語言里就會出現類似數加字符串這種運算,可能並不是程序員的預期和本意,所以比起強類型性語言而言經常會出現很多無聊的BUG。

再更新:

上面發展出了父類之后,我們發現編程還是有問題的,小數類:

小數類 {




}

如果我們需要一個能自動實現結果四舍五入的小數計算類,同時又需要一個不需要的,怎么辦呢,難道要寫兩個類嗎?不要。

所以做出了“實例”或者“對象”這一東西,首先把類改成:

小數類 {
標識變量:是否四舍五入
標識變量:是否限定小數點后位數
構造函數(設置上面的標識)
加(會根據上面兩個標識變量輸出不同結果)
減(會根據上面兩個標識變量輸出不同結果)
乘(會根據上面兩個標識變量輸出不同結果)
除(會根據上面兩個標識變量輸出不同結果)
}

這樣,我們就寫一個類,但是通過構造函數,把一份代碼,構造出了行為稍微有點不同的兩個實例供我們使用,這時候名詞來了,不能進行實例化微調化的類,叫做靜態類,函數們的行為是固定的。不能實例化的類,其實只是函數們的一個集合歸納,只是對函數進行了整理,功能的強大和編碼的自由靈活度是不夠的。

能夠進行實例化,變化出各種行為各自不大一樣的實例的類,我們一般就把它們叫做類了,因為最常見。

程序員們也就能保持代碼簡單的同時而又可以很方便進行代碼行為微調了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM