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