發(fā)布于:2020-12-24 16:14:12
0
105
0
在1981年8月的Byte雜志的Byte雜志中,David Robson公開承認自己與許多熟悉的命令式,自上而下的軟件背道而馳,從而成為許多人對“面向?qū)ο蟮能浖到y(tǒng)”的介紹,編程習(xí)慣。許多不知道計算機如何工作的人都覺得面向?qū)ο缶幊痰南敕ê茏匀?。相反,許多有計算機經(jīng)驗的人最初認為面向?qū)ο蟮南到y(tǒng)有些奇怪。
可以說,幾代人以后,將代碼組織成更大的,有意義的對象以對問題的各個部分進行建模的想法一直困擾著程序員。如果將它們用于自上而下的編程或函數(shù)式編程(將代碼元素視為精確的數(shù)學(xué)函數(shù)),則需要一些時間來習(xí)慣。在最初的大肆宣傳承諾對模塊化和組織大型代碼庫進行改進之后,該想法被過度應(yīng)用。在OOP之后是OOA(面向?qū)ο蟮姆治觯┖蚈OD(面向?qū)ο蟮脑O(shè)計)之后,很快感覺到,您在軟件中所做的一切都必須分解為對象及其相互之間的關(guān)系。然后評論家趕到了現(xiàn)場,其中一些人非常失望。
一些人聲稱,在OOP下,編寫測試會更加困難,并且需要格外小心地進行重構(gòu)。重用代碼時會產(chǎn)生額外的開銷,Erlang的創(chuàng)建者將其描述為一個案例,當您想要一個香蕉,但是卻得到了一只拿著香蕉的大猩猩。一切都帶有隱性,不可避免的環(huán)境。
描述這種解決問題的新方法的其他方式包括命令式程序員之間的類比:“廚師或化學(xué)家,遵循食譜和公式以達到期望的結(jié)果”,而面向?qū)ο蟮某绦騿T之間的類比為“相關(guān)的希臘哲學(xué)家或19世紀自然主義者”以及對編程世界中生物和地點的正確分類法和描述?!?/span>
成功只是巧合嗎?
目前,OOP仍然是主要的范例之一。但這可能是由于碰巧是OOP的語言的成功所致。 Java,C ++和Kotlin統(tǒng)治了Android的移動版,而Swift和iOS的Objective-C成為移動版,因此除非您了解面向?qū)ο蟮姆椒?,否則您將無法開發(fā)移動版軟件。對于網(wǎng)絡(luò),它是JavaScript,Python,PHP和Ruby。
問為什么OOP這么多被廣泛使用的語言可能會混淆因果關(guān)系。理查德·費爾德曼(Richard Feldman)在講話中指出,這可能只是巧合。 C ++是由Bjarne Stroustrup在1980年代初期開發(fā)的,最初是對C編程語言的擴展。 C ++以C為基礎(chǔ),增加了面向?qū)ο蟮墓δ?,但Feldman認為它在從C進行整體升級方面變得很流行,包括類型安全性,并增加了對自動資源管理,通用編程和異常處理等的支持。
然后Java希望吸引C ++程序員,并在OOP方面加倍投入。最終,Sun Microsystems希望通過使采用Java的開發(fā)人員最熟悉的方式來重復(fù)C ++技巧。
由于當時Java與Web瀏覽器的獨家集成,數(shù)百萬開發(fā)人員迅速轉(zhuǎn)向Java。這樣看來,OOP似乎只是在兜風(fēng),而不是推動成功。
OOP可以做什么呢?
OOP有一些有價值的方面,即使它有缺點,也有一些方面使其無處不在。讓我們看一下OOP的基石。
封裝。這意味著,如果可能的話,通常會將數(shù)據(jù)從語言的其他部分隱藏起來(放在膠囊中)。 OOP默認封裝數(shù)據(jù);對象包含數(shù)據(jù)和影響數(shù)據(jù)的方法,良好的OOP實踐意味著您提供了getter和setter方法來控制對數(shù)據(jù)的訪問。這樣可以防止可變數(shù)據(jù)被隨意更改,并使應(yīng)用程序數(shù)據(jù)更安全。
據(jù)說,這是OOP的最大好處之一。盡管它最常與面向?qū)ο蟮木幊滔嚓P(guān)聯(lián),但概念本身實際上與它是分開的,可以在不使用對象的情況下實現(xiàn)。抽象是此處封裝的補充概念。在封裝隱藏內(nèi)部信息的地方,抽象提供了易于使用的公共數(shù)據(jù)接口。在任何情況下,它都不是唯一的OOP功能,并且可以通過隔離系統(tǒng)功能或一組數(shù)據(jù)以及模塊內(nèi)對這些數(shù)據(jù)的操作的模塊來完成。
遺產(chǎn)。因為可以將對象創(chuàng)建為其他對象的子類型,所以它們可以從那些對象繼承變量和方法。這允許對象支持由先前類型定義的操作,而不必提供自己的定義。目的是不要重復(fù)自己—難以維護同一代碼的多次使用。但是函數(shù)式編程也可以通過可重用的函數(shù)來實現(xiàn)DRY。內(nèi)存效率也一樣。即使繼承確實對此有所貢獻,F(xiàn)P中的閉包概念也是如此。
雖然繼承是面向?qū)ο蟮奶囟ǜ拍?,但有人認為繼承可以通過組合更好地實現(xiàn)。如果失去繼承,則對象和方法將迅速溶解為結(jié)構(gòu)和過程的語法糖。注意:繼承對于允許多態(tài)性也是必要的,我們將在下面討論。
多態(tài)性。從字面上講,此概念可以改變形狀,它允許一個對象或方法(無論是通用對象,接口還是常規(guī)對象)充當其他對象和方法的模板。有多種形式的多態(tài)性。單個函數(shù)可以重載,變形并適應(yīng)其所在的任何類。面向?qū)ο蟮木幊虄A向于使用許多子類型多態(tài)性和即席多態(tài)性,但是同樣,這不限于OOP。
好像在2020年一樣,OOP并沒有其他編程范例可以做的那么多,而優(yōu)秀的程序員將在克服復(fù)雜性的斗爭中一起使用多種范例中的策略。例如,如果您查看與OOP與功能編程下的問題相關(guān)的最頻繁出現(xiàn)的標簽,則JavaScript會同時彈出。
會發(fā)生什么?
OOP取得了巨大的成功。這種成功可能是由OOP支持并受其支持的龐大行業(yè)的結(jié)果。
那么開發(fā)人員自己呢?我們今年的開發(fā)人員調(diào)查顯示,他們獲得了越來越多的購買影響力。好吧,如果我們也看看開發(fā)人員更喜歡使用哪種工具,Haskell和Scala就是最受歡迎的編程語言之一。 Scala讓您獲得第二高的薪水。因此,也許有了更多的FP福音,他們也會爬上最受歡迎的語言。
但是有一些動靜,像Twitter這樣的大公司幾乎完全在Scala代碼上運行其后端。最近一直使用Haskell和許多主要OOP語言的Facebook也采用了功能功能。 .NET具有LINQ和Java 8引入的Lambda。盡管在ES6中引入了類,但是JavaScript的功能越來越強大。 Swift可能是介于面向?qū)ο蠛凸δ苷Z言之間的快樂媒介。因此,也許無需選擇:您也可以使用Cake和EatCake()類。
特別感謝Ryan,他的出色見解和編輯對這篇文章有所幫助。