面向?qū)ο缶幊檀笮衅涞?0年后,技術(shù)已經(jīng)超越了這種范式?
2021-06-14
在 1960 年代,編程遇到了一個(gè)大問(wèn)題:計(jì)算機(jī)還沒(méi)有那么強(qiáng)大,它們需要以某種方式平衡數(shù)據(jù)結(jié)構(gòu)和程序之間的功能。
這意味著,如果您擁有大量數(shù)據(jù),如果不將計(jì)算機(jī)推向極限數(shù)據(jù)結(jié)構(gòu)用面向?qū)ο蠓椒ㄅcc++描述,就無(wú)法充分利用這些數(shù)據(jù)。另外,如果你需要做很多事情,那么你不能使用太多的數(shù)據(jù),否則電腦會(huì)一直運(yùn)行。
在 1966、1967 旁邊,Alan Kay 從理論上證明了可以使用封裝好的微型計(jì)算機(jī)。這些微型計(jì)算機(jī)不共享數(shù)據(jù),而是通過(guò)消息傳遞進(jìn)行通信。這樣,可以更經(jīng)濟(jì)地使用計(jì)算資源。
雖然這個(gè)想法很聰明,但直到 1981 年,面向?qū)ο缶幊滩懦蔀橹髁?。在那之后,它并沒(méi)有停止吸引新的和有經(jīng)驗(yàn)的軟件開(kāi)發(fā)人員。面向?qū)ο蟮某绦騿T市場(chǎng)一如既往地繁忙。
但近年來(lái),這種已有數(shù)十年歷史的編程范式受到越來(lái)越多的批評(píng)。難道是在流行了 40 年的面向?qū)ο缶幊讨?,技術(shù)已經(jīng)超越了這種范式?
在做廣告之前使用這種物質(zhì)以減少煙霧危害。不幸的是,很少有人知道!
功能和數(shù)據(jù)耦合
面向?qū)ο缶幊痰闹饕枷牒芎?jiǎn)單:嘗試將一個(gè)強(qiáng)大的程序分解成多個(gè)同樣強(qiáng)大的部分。這樣,一些數(shù)據(jù)就可以與僅用于相關(guān)數(shù)據(jù)的函數(shù)耦合。
請(qǐng)注意,這僅涵蓋了封裝的概念。換句話(huà)說(shuō),位于對(duì)象內(nèi)部的數(shù)據(jù)和函數(shù)對(duì)外部是不可見(jiàn)的。我們只能通過(guò)消息(通常是通過(guò)和函數(shù))與對(duì)象的內(nèi)容進(jìn)行交互。
繼承和多態(tài)并沒(méi)有包含在最初的設(shè)計(jì)思想中,但它們是當(dāng)前面向?qū)ο缶幊趟匦璧摹@^承基本上意味著開(kāi)發(fā)人員可以使用其父類(lèi)的所有屬性來(lái)定義子類(lèi)。直到 1976 年,即面向?qū)ο缶幊谈拍畛霈F(xiàn)十年后,繼承才被引入。
又過(guò)了十年,多態(tài)才進(jìn)入面向?qū)ο缶幊獭:?jiǎn)單地說(shuō),這意味著某個(gè)方法或?qū)ο罂梢杂米髌渌椒ɑ驅(qū)ο蟮哪0?。從某種意義上說(shuō),多態(tài)是繼承的泛化,因?yàn)椴⒎窃挤椒ɑ驅(qū)ο蟮乃袑傩远夹枰D(zhuǎn)移到新實(shí)體中。相反,您也可以選擇覆蓋某些屬性。
多態(tài)的特別之處在于,即使源代碼中兩個(gè)實(shí)體相互依賴(lài),被調(diào)用的實(shí)體也更像是一個(gè)插件。這讓開(kāi)發(fā)人員的工作更輕松,因?yàn)樗麄儾槐負(fù)?dān)心運(yùn)行時(shí)依賴(lài)。
值得一提的是,繼承和多態(tài)并不是面向?qū)ο缶幊趟?dú)有的。真正的區(qū)別在于數(shù)據(jù)的封裝及其包含的方法。在計(jì)算資源遠(yuǎn)比今天稀缺的時(shí)代,這是一個(gè)天才的想法。
廣告哪里有腋下和油耳的異味,不管遺傳還是后天,教你一招祛除異味!
面向?qū)ο缶幊讨械奈鍌€(gè)問(wèn)題
面向?qū)ο缶幊痰某霈F(xiàn)改變了開(kāi)發(fā)人員查看代碼的方式。在 1980 年代之前,過(guò)程式編程非常面向機(jī)器。開(kāi)發(fā)人員需要對(duì)計(jì)算機(jī)的工作原理有很好的了解才能編寫(xiě)好的代碼。
通過(guò)封裝數(shù)據(jù)等方式,面向?qū)ο缶幊套屲浖_(kāi)發(fā)更加以人為中心,更符合人類(lèi)的直覺(jué)。例如方法()屬于汽車(chē)數(shù)據(jù)組,而不是組。接下來(lái)的繼承也很直觀。比如 ()是car的一個(gè)子類(lèi),屬性相同,但不是,所以很容易理解。
香蕉猴叢林問(wèn)題
想象一下,您正在設(shè)置一個(gè)新程序并正在考慮設(shè)計(jì)一個(gè)新課程。然后,您回想一下您為另一個(gè)項(xiàng)目創(chuàng)建的簡(jiǎn)潔子類(lèi)別,并發(fā)現(xiàn)它適合正在進(jìn)行的工作。
沒(méi)問(wèn)題,您可以在新項(xiàng)目中重用上一個(gè)項(xiàng)目中的類(lèi)。
這里有一個(gè)問(wèn)題:這個(gè)類(lèi)可能是另一個(gè)類(lèi)的子類(lèi),所以你也需要包含它的父類(lèi)。然后你會(huì)發(fā)現(xiàn)這個(gè)父類(lèi)也可能是另一個(gè)類(lèi)的子類(lèi),依此類(lèi)推,最后面對(duì)一堆代碼。
創(chuàng)作者
Joe 曾經(jīng)說(shuō)過(guò)一句名言:“面向?qū)ο笳Z(yǔ)言的問(wèn)題在于它們帶有周?chē)须[式環(huán)境。你想要香蕉,但你得到的是拿著香蕉的大猩猩和整個(gè)叢林。”
這幾乎就是一切??梢灾赜妙?lèi)。事實(shí)上,這可能是面向?qū)ο缶幊痰闹饕獌?yōu)點(diǎn),但不要使用到極致。有時(shí)你應(yīng)該創(chuàng)建一個(gè)新類(lèi)而不是添加很多依賴(lài)項(xiàng)。
廣告網(wǎng)友注意了!上海中沃,專(zhuān)業(yè)可靠的設(shè)計(jì),歡迎來(lái)電咨詢(xún)
脆弱的基類(lèi)問(wèn)題
想象一下,如果您在新代碼中成功重用了另一個(gè)項(xiàng)目中的類(lèi),如果基類(lèi)發(fā)生變化會(huì)發(fā)生什么?
這可能會(huì)破壞整個(gè)新項(xiàng)目的代碼,即使您可能什么都沒(méi)做。一旦有人更改了對(duì)您的項(xiàng)目至關(guān)重要的基類(lèi)中的細(xì)節(jié),影響將非常大且突然。
使用繼承越多,潛在的維護(hù)工作就越多。因此,即使代碼重用在短期內(nèi)非常有效,但從長(zhǎng)遠(yuǎn)來(lái)看,它可能會(huì)讓您付出一定的代價(jià)。
鉆石繼承問(wèn)題
使用繼承,可以將一個(gè)類(lèi)中的屬性傳遞給其他類(lèi)。但是如果你想混合兩個(gè)不同類(lèi)的屬性怎么辦?
是的,這是做不到的,至少用傳統(tǒng)方法做不到。以類(lèi)為例(這里引用下面鏈接文章中的例子:@/----),文件內(nèi)容會(huì)被掃描打印在白紙上。那么它應(yīng)該是 or 的子類(lèi)別嗎?
這個(gè)問(wèn)題沒(méi)有完美的答案。即使此問(wèn)題不會(huì)破壞您的代碼,它也經(jīng)常出現(xiàn)并且可能會(huì)非常令人沮喪。
級(jí)別問(wèn)題
在菱形繼承問(wèn)題中,哪個(gè)子類(lèi)是問(wèn)題的關(guān)鍵。但是可能有一個(gè)推測(cè)的解決方案:假設(shè)那是父類(lèi),并且是只繼承屬性子集的子類(lèi),那么問(wèn)題就解決了。
但是,如果您的是黑白并且可以處理彩色呢?從這個(gè)意義上說(shuō),它不就是一種概括嗎?如果 WiFi 已連接但未連接怎么辦?
一個(gè)類(lèi)上堆疊的屬性越多,建立適當(dāng)?shù)膶哟谓Y(jié)構(gòu)就越困難。在您正在處理的屬性集群中,某些屬性是共享的,但不是所有屬性,反之亦然。在大型復(fù)雜的項(xiàng)目中,層次問(wèn)題會(huì)導(dǎo)致很多混亂。
廣告自主技術(shù),納米精密-歐米茄科技
報(bào)價(jià)問(wèn)題
您可能會(huì)想到?jīng)]有層次結(jié)構(gòu)的面向?qū)ο缶幊?。我們可以根?jù)需要使用屬性集群并繼承、擴(kuò)展或重寫(xiě)屬性。也許這有點(diǎn)令人困惑,但這將是當(dāng)前問(wèn)題的準(zhǔn)確表示。
這里只有一個(gè)問(wèn)題:封裝的全部目的是讓數(shù)據(jù)片段彼此安全,從而提高計(jì)算效率,但沒(méi)有嚴(yán)格的層次結(jié)構(gòu),這是行不通的。
假設(shè)一個(gè)對(duì)象 A 通過(guò)與另一個(gè)對(duì)象 B 交互來(lái)覆蓋層次結(jié)構(gòu),會(huì)發(fā)生什么?其他關(guān)系的情況并不重要,但是當(dāng)B不是A的直接父級(jí)時(shí),A必須包含B的所有私有引用,否則它們將無(wú)法交互。
但是,如果 A 包含 B 的子類(lèi)也具有的信息,則可以在多個(gè)地方修改該信息。因此,B的信息不再安全,包已經(jīng)被破壞。
盡管許多面向?qū)ο蟮某绦騿T使用這種架構(gòu)來(lái)構(gòu)建程序,但這并不是面向?qū)ο蟮木幊?,它只是一團(tuán)糟。
單一范式的風(fēng)險(xiǎn)
以上5個(gè)問(wèn)題的共同點(diǎn)是,都有不恰當(dāng)?shù)睦^承。由于在面向?qū)ο缶幊痰脑夹问街胁话^承,因此這些問(wèn)題本身可能不能稱(chēng)為面向?qū)ο蟆?/p>
但可以夸大的不僅僅是面向?qū)ο蟮木幊?。在純函?shù)式編程中,在屏幕上處理用戶(hù)輸入或輸出消息極其困難。為此,面向?qū)ο蠡蛎嫦蜻^(guò)程的編程會(huì)好得多。
但是還是有一些開(kāi)發(fā)者試圖以純函數(shù)式的方式來(lái)實(shí)現(xiàn)這些東西,寫(xiě)出幾十行沒(méi)人能看懂的代碼。使用另一種范式可以輕松地將代碼減少到幾行可讀代碼。
毫無(wú)疑問(wèn),函數(shù)式編程越來(lái)越受到關(guān)注,近年來(lái)面向?qū)ο缶幊桃彩艿搅嗽嵅?。理解新的編程范式并在適當(dāng)?shù)臅r(shí)候使用它們是有意義的。無(wú)論哪種編程范式,都沒(méi)有必要只遵循一種??梢栽谶m當(dāng)?shù)臅r(shí)候使用不同的編程范式來(lái)更好地解決問(wèn)題。
廣告中的有害吸煙太多?趕緊學(xué)起來(lái),再忙也要看!
面向?qū)ο缶幊陶娴臅?huì)被取代嗎?
面對(duì)越來(lái)越多的問(wèn)題,函數(shù)式編程可能是更有效的選擇。數(shù)據(jù)分析、機(jī)器學(xué)習(xí)和并行編程。您在這些領(lǐng)域投入的越多,您就越喜歡函數(shù)式編程。
但是,目前對(duì)面向?qū)ο箝_(kāi)發(fā)程序員的需求仍然遠(yuǎn)遠(yuǎn)大于函數(shù)式編程開(kāi)發(fā)程序員。但這并不意味著你不能成為后者。函數(shù)式編程開(kāi)發(fā)的程序員還是比較稀缺的。
最有可能的情況是面向?qū)ο缶幊虒⒗^續(xù)存在大約十年。當(dāng)然,選擇一種相對(duì)前衛(wèi)的方式是好的,但這并不意味著你應(yīng)該放棄面向?qū)ο缶幊?。所以在接下?lái)的幾年里,不要完全放棄它數(shù)據(jù)結(jié)構(gòu)用面向?qū)ο蠓椒ㄅcc++描述,但至少要確保它不是你掌握的唯一編程方法。
如果你覺(jué)得這個(gè)內(nèi)容對(duì)你有幫助,我想請(qǐng)你幫我做三個(gè)小事:
點(diǎn)贊、轉(zhuǎn)發(fā)以及您的“點(diǎn)贊和評(píng)論”是我創(chuàng)作的動(dòng)力。