面向對象編程的重要性在哪?

對於OO我是菜鳥,目前也只是大致了解C sharp和Python的語法。至於C++、java沒學過,我不是cs相關專業的。

RT,起先看到知乎上很多人說OO的好處就是提高程序可維護性。後來又有人說OO抽象封裝層數一多會導致難以修改和維護。

百度百科是說【......更利於人理解的方式對於複雜系統的進行分析、設計與編程,來提高編程的效率】

我現在的感覺是OO除了圖形界面必須要用,貌似沒有必要用到別的地方。

OO的重要性到底體現在哪?


沒什麼只有OO能做到,OO更多的是給了你一種能力,一種忽略細節的能力:忽略的越多,人類有限的智力就可以容納越多越複雜的問題,並由此提高生產效率。

任何抽象的本質都是忽略,OO剛好是其中一種。


解耦


基礎是封裝:信息隱藏,簡化形參設計;OOP使得Reactive Programming (Actor模型,消息通信,事件機制,非同步)的實現變得自然。


減少全局變數。。。


2016-5-10 16:03:補充

個人覺得,相對於面向過程的思維和編程,優點是直接,編程直奔主題和結果,早期的開發,設計成本低。對於規模小的功能和實現,一次性開發和使用的程序,以及對於很多不確定的程序的開發初期,很自然的會採用這種方法。在初學 c 語言時,尤其是採用和強化了這種思維模式。

缺點是通常沒什麼層次,很容易使得「可復用」的部分和具體的「邏輯」耦合在一起,使得裡面的復用部分往往也難以復用。所以,面向過程的代碼,容易被淹沒在沒有層次感的大量代碼之中。對於項目的維護和可重構來說,是不利的。

而面向對象編程,就封裝性來說,對演算法,數據做了一些分類。對外暴露了經過設計的介面。這使得業務邏輯也被劃分的更清晰和更有層次感,使得程序員可以每次專註於一個整體中具體的細分局部來工作。因此,有利於多個人協同合作。

如果僅僅使用了封裝性,繼承性,那麼就僅僅是基於對象。面向對象最重要的特性,是利用其多態性(也就是說,使用 OO 時,你只有使用虛函數,並且通過祖先的介面來操作它們,你才能感受和發揮出 OO 語言的威力和優點,以及 OO 的美妙之處),最終對項目的層次定義的更加清晰合理。在不影響整體設計框架的情況下,你可以通過多態性,隨時定義,調整和定製某一個具體對象的個性化行為。

當然,要做到這一點也不是很容易,最終結果通常不可能是你最早就能預見的。往往需要隨著開發的進行,不斷的調整各個介面的定義,才能逐漸達到最終的合理狀態。因此,開發過程中初期開發成本還是略高的。等到這些定義成熟以後,它的易用性,和可維護性上面,都要比面向過程的代碼更有優勢。

此外,編譯器對 OO 編程語言的輔助作用,對程序員來說是一個很重要的幫助。例如,編譯器承擔了析構臨時對象的責任(程序員只需要專註於把析構函數寫好就行了)。這使得我們在使用對象時,減輕了一些內存管理和資源維護的負擔。例如,在 c 語言的一個函數中,如果申請和打開多個資源,你需要認真的追蹤,負責它們的回收和關閉(尤其是當函數在中間就 return 的情況)。在 c++ 中則可以很輕鬆的隨時定義一個臨時對象就夠了(因為編譯器會在適當的時候析構它們)。

在下面的原答案中,我主要是提出了對曾經我看到的一些觀點的不認同,一些人對於 OO 的理解過於僵化,以及把非 OO 視為洪水猛獸,這些看法太絕對。就和一些人套用設計模式一樣,太生硬太形式化就不好了。

你有兩種選擇:OO 的,非 OO 的。

----

面向對象最重要的功能,是在語言層面,做出一些歸類和劃分。這給出了額外信息,有助於提高程序的可維護性,和可控。

也就是說,傳達出,數據之間,函數之間,數據和函數之間的疏密和邏輯關係。通過對複雜任務,化整為零,實現分工協作和任務簡化,這類似分治法。

同時,在編程模型中建立了對象的概念,通常更加切合人類的思考習慣,通過合理的封裝,設計良好的對象介面,從而幫助人們更容易開發和管控自己的代碼。

關於樓主提問,我補充下,OO 的選擇 和 GUI 是完全獨立無關的。GUI 也可以以面向過程的方式開發。在適合 OO 的各種場合(不一定是 GUI),採用 OO 來編程當然也是十分有益的。

然後面向對象的使用,人們很容易僵化,要謹防:

(1)過度OO。不必要的加深對象關係網路深度,會降低程序的可維護性和可控性,最終失控而導致項目失敗。

(2)一些人對面向過程才去完全對立,這是一種教條主義和僵硬呆板的理解。實際上絕對的 OO,必然不是最正確的。不管強行 OO 只能是弄巧成拙的愚蠢人。意識不到,OO 並不是適用所有模型,或者說,很多場合,沒有必要 OO和沒有 OO 的特別收益。

實際情況,一般是 OO 和 面向過程兩者的合理結合組合,來解決問題。而不是非此即彼的關係。

以前我經常在技術論壇看到有人說,這不 oo 呀,他們要是看到 oo 語言的彙編結果,只怕要痛苦自殺了。。。。

--

2016年7月18日補充:

我承認,使用 OO 中的多態 / 面向介面的編程,確實是 OO 中最讓人感到享受的優美之處。會讓你由衷的產生 WOW 的讚歎。

當然,它也有缺點,比如說隱藏了一些東西在機制之下,代碼流隱晦了很多,它不像 C 語言那麼直觀,沒有隱藏,你很清楚都調用了什麼東西。這有時候會讓你分析流程和 debug 的時候,找到具體被執行的代碼片段時,顯得有些繁瑣和費勁。

此外,還有一種很常見的現象,雖然我們很像面向一個通用介面編程,下面的個性越個性越好,越多態越好,然而有得就有失,所以也總是會有一些對象,它就是太個性以至於另類的有點過頭,它大部分行為都可以歸於通用介面中,然而它又有一些個性化行為,只有它有,而其他人都不需要有。

這時候就會顯得很尷尬。如果我們要把通用介面指針,根據情況,轉換成這個對象的指針,那麼就破壞了 OO 的優雅和優美!強迫症都犯了!

然而,如果我們為了介面的統一,把這個對象獨有的行為添加到通用介面中去,那麼就意味著通用介面看起來有點彆扭,掛著一個大家一看就知道是專屬於張三需要的東西。其他人都不需要。。不倫不類的。

此外,OO 有一個繼承樹,在開發初期是很不穩定的,它在開發過程中往往隨著發現新的需要而不斷的調整和修正,這個樹是牽一髮而動全身的關係,一動就會比較麻煩,所以這時候的開發成本是有點高的。

當你把一些通用行為在比較高層(繼承樹中距離 root 距離小)的介面中實現,可以讓它的子孫輩低成本的享用這些通用功能的時候,這時候感覺還是蠻爽的。


為了抽象


OO三大件 :封裝,繼承,多態。

封裝是為了『去除全局變數』。

繼承是為了『去除代碼dup』。

多態是為了能讓『繼承』得以成立(巨汗)。

由此可見,OO重要性也就兩點,「1.去全局變數, 2.去代碼dup」。

那麼為什麼這兩點這麼重要?

親手寫過並且跟蹤維護過大規模應用的人自然明白,

或者接收並維護過『全局變數,代碼dup滿天飛項目』的人,也能明白。


這一點,也許可以從面向對象的誕生說起

在面向對象出生之前,有一個面向過程的人,它將整個待解決的問題,抽象為描述事物的數據以及描述對數據進行處理的演算法,或者說數據處理過程。當問題規模比較小,需求變化不大的時候,面向過程工作得很好。

可是(任何事物都怕「可是」二字),讓問題的規模越來越大越來越複雜,需求變化越來越快的時候,面向過程就顯得力不從心了,想像一下,當你根據需求變化修改了某個結構體,你不得不修改與之相關的所有過程函數,而一個過程函數的修改,往往又會涉及到其他數據結構,在系統規模較小的時候,這還比較容易解決,可是當系統規模越來越大,涉及到多人協作開發的時候,這肯定是一場噩夢。這就是那場著名的軟體危機。

為了解決這場軟體危機,面向對象應運而生了(有問題的出現,必然就有解決問題的方法的出現,英雄人物大都是這樣誕生的)

我們知道,面向對象的三板斧分別是封裝,繼承和多態,他用封裝將問題中的數據和對數據進行處理的函數結合在了一起,形成了一個整體的對象的概念,這樣更加符合人的思維習慣,更利於理解,自然在理解和抽象一些複雜系統的時候也更加容易。他用繼承來因對系統的擴展,在原有系統的基礎上,只要簡單繼承,就可以完成系統的擴展,而無需重起爐灶。他用多態來應對需求的變化,統一的借口,卻可以有不同的實現。

可以說,面向對象思想用他的三板斧,在一定程度上解決了軟體危機,我想這是他重要性的根本體現。


OO只是一種解決問題的方法

封裝,繼承,多態...是面向對象的基本特徵

但是沒有一把鑰匙可以打開世界上所有的鎖...


對於初學者來說, oo的最明顯的好處可能不是在你寫代碼的時候感受到的.

而是在你用別人的庫的時候發現的...


會真誠直接地告訴你找不到對象


相比初代紙帶程序與未來自然語言的模塊化編程模型,面向對象只是一小步,它在思維上幫助越來越多的人學會編程和喜歡編程,很明顯,只要編程還沒正式進入小學課本我們就還不滿足。


基本沒用到,只佔我寫的代碼量中一兩成吧。取決於你所要做的項目類型。沒有什麼萬能的什麼都適合的語言。也並非什麼問題都適合用OO來解決的,而要看你的「問題域」,是否天然地適合對象建模。

3類熱衷OO的人,你是哪一種?

1,寫OO書賣OO書搞OO培訓的,無可厚非。

2,被上述人忽悠的,不管什麼問題都想OO化,然後寫出的代碼像梵高的畫一樣扭曲。

3,在工作中真正感覺有用的。

我不想批OO,只是討厭OO萬能論、OO至上論。


如果真的想發自內心地理解「面向對象」,請一定要從多人協作的項目做起。

比如中途插入某個 fork,跟著版本一起成長。在這樣的項目里,OO 的風格並不一定非常明顯,但 OO 的動機一定非常迫切。


OO提醒浸淫於技巧者計算機和計算機語言都是為了讓大多數人更加簡單地解決問題而創造出來的。


你寫10萬行代碼自然就明白了,現在告訴你沒啥用


從接觸第一門語言到現在為止已經差不多10年時間了。說下個人的觀點。

一、編程到底是個什麼事物?

編程(程序設計)實際上是一個對現實世界中的事物抽象,並由計算機語言實現的過程。

核心的步驟就包含三個:理解、抽象、實現。

不同的理解思路,會導致完全不同的抽象結果;

不同的抽象結果就會提供各不同的理解。

最後根據理解和抽象,由特定的語言完成時間,但其結果要想完全理解還需要前兩個步驟支撐。

有點像建築中的「房子是什麼,房地產設計,蓋房子」。(推薦《建築的永恆之道》)

二、編程的發展過程到底有哪些?

程序設計的歷史,記得以前知乎上有專門介紹編程的歷史,具體地址忘記了。但可以參考百度百科中《計算機歷史:http://baike.baidu.com/view/17139.htm#5》

按照我的理解大致的幾個主要階段:

1、計算機程序設計歷史前階段;主要是紙帶、存儲器等原始方式。

2、計算機語言初級階段;主要以彙編語言為主,面向的主要內容是「數據存儲+指令集」;

3、計算機廣泛工業語言設計階段;主要以C語言為主的大面積應用,此時由C語言更面向人易懂的方向發展。並且操作系統,編譯器,資料庫軟體開始發展;面向的主要內容是「程序=演算法+數據結構」。此時在計算機軟體設計學科中主要運用的還是「面向過程」的設計思路。

4、計算機語言高級發展階段。主要是一些面向對象語言的出現。主要體現在C++語言的出現。主要面向的內容是「應用=對象+通訊」的方式。甚至很多語言開始「一切皆對象」的設計理念。面向對象的語言主要在該階段得到了大力提倡。因為C++的複雜,Java的出現降低了複雜度,又充分利用了面向對象的特點。讓面向對象的設計更是得到了大面積的推廣和應用,尤其在企業級應用開發中。

5、各類語言頻繁出現的繁榮各階段。各類變成設計語言如面向WEB變成,函數式語言,面向並發的語言,終端設備的編程語言等等;這個階段不好做評論。

三、編程的過程解決的問題有哪些?

1、彙編語言:解決CPU指令集和存儲系統的交互問題,提供「可編程」的能力

2、面向過稱語言:提供小面積的問題解決思路,一個系統的代碼如果不多,通過面向過程思路將系統劃分為多個過程(多個函數+各類數據結構)進行系統設計。提供了初級規模的系統設計問題。

3、面向對象語言:當面向過程面對複雜的系統,複雜的世界時。如何「更好的理解和抽象」編程問題,變得更加重要。通過面向對象語言的特點「封裝、繼承、多態」,讓程序分析和設計能容納更大的編程範圍和系統規模,也讓程序設計人員更好的理解和抽象提供了非常重要的作用。

4、面向**語言:面向WEB,面向高並發,面向切面,函數式語言,終端開發等是在現有程序設計語言基礎上不斷改進,並解決特定領域特定問題的發展衍生;

四、面向對象編程思想的重要性體現是什麼?

大家都知道,面向對象的三大特性「封裝、繼承、多態」,但個人認為其中的「封裝」是面向對象的最核心的特點。

究其原因,主要是「封裝」讓一個人可以理解的系統範圍可以變得更廣,可以讓我們「更好的理解和抽象」我們所看到的世界。

之前一個老師提到面向對象時,提到的是「間接」,我想間接也可以認為是「封裝」的升級版。

而面向對象編程思想的作用,可以看看我們常見的編程原則《見:程序設計的18大原則http://hi.baidu.com/andida591/item/54f8d2dc5e2a9ce1795daafa》,面向對象的思想能更好的指導我們滿足這些原則,從而帶來「可維護性,可擴展性,可理解性」等讓我們能在效率和水平上更加長進的東西。

以上也是個人的一些總結,不用什麼引經據典,但如果知友想更好的了解計算機程序設計這個行當,還是建議能把計算機的歷史、程序設計的歷史、以及C,C++,Java能學習一遍,更能體會到編程思想在幾門語言中的側重和發展演變原因。


Barney Stroustrup說過,C++能有現在的發展,勝利的並不是語言本身,而是一種思想。在做程序設計的時候,OOD這種思想指導你除了思考一個task的完成需要哪些過程,哪些資源,還推動你去思考完成這個task需要的對象(額,我這不是廢話么。) 換句話說,OOD更好的映射(抽象)了現實與程序設計,而程序設計在解決現實問題的時候本身就是把現實問題最終映射(抽象)成了數學邏輯來運算。當然,一些OOD相關的特性,例如繼承、封裝、多態、介面等等除了提高程序的抽象能力,還提高了課維護性。

最後,發個純屬搞笑的(zz):

Scheme 大法好

天滅過程式 退C保平安

人在做 天在看 賦值語句留禍患

指針亂用天地滅 趕緊重寫保平安

誠心誠念SICP好 Scheme大法平安保

眾生都為函數來 現世險惡忘前緣

Scheme弟子說真相 教你編程莫拒絕

早日擺脫面向過程 早日獲得新生

上網搜「九評丹尼斯·里奇」 有真相


面向對象就是一個高度專業化的公司。公司的盈利模式,組織架構等等都很清晰。每個員工的職責,能力值,風險值,彙報對象都非常精確,員工之間有充分必要的了解,每個員工的工作內容,員工之間的協作程序也都已經標準化。

而另一家公司,請的都是臨時工。。。


膾炙人口。

是一種尚可一用的抽象機制——用類來刻畫概念。

廣大人民群眾對其喜聞樂見、約定俗稱、將錯就錯。


推薦閱讀:

想自學虛幻4引擎,準備以後和熟人一起組建遊戲工作室,請問應該以什麼流程去學習?
僅僅從職業發展前景考慮,做編譯器開發或操作系統開發哪個方向更有前途?
本科計算機專業的數學應該達到怎樣的水平?
架構、構架、結構、框架之間有什麼區別?

TAG:Python | 編程 | 面向對象編程 | C |