新聞中心
本文轉(zhuǎn)載自公眾號“讀芯術(shù)”(ID:AI_Discovery)。

創(chuàng)新互聯(lián)主營石拐網(wǎng)站建設的網(wǎng)絡公司,主營網(wǎng)站建設方案,app開發(fā)定制,石拐h5微信小程序搭建,石拐網(wǎng)站營銷推廣歡迎石拐等地區(qū)企業(yè)咨詢
編程在上世紀60年代遇到了一個大問題:計算機那時還沒有那么強大,需要以某種方式在數(shù)據(jù)結(jié)構(gòu)和進程之間分配容量。這意味著如果擁有大量數(shù)據(jù),那么在不將計算機推向極限的情況下,很多事情將無法完成。另一方面,如果需要做很多事情,那么就不能使用過多的數(shù)據(jù),否則計算機將永遠占據(jù)空間。
接著艾倫·凱(AlanKay)大約于1966年或1967年得出理論認為可以使用封裝的微型計算機,這些微型計算機不共享數(shù)據(jù),而是通過消息傳遞進行通信。這樣可以更加經(jīng)濟地使用計算資源。
盡管這個想法很巧妙,但直到1981年,面向?qū)ο缶幊滩懦蔀橹髁鳌5菑哪且院?,它并沒有停止吸引軟件開發(fā)新手和老手。面向?qū)ο缶幊痰某绦騿T一如既往的繁忙。
但近年來,這一已有十年歷史的范式受到越來越多的批評。難道是在面向?qū)ο蟪绦蛟O計大行其道40年之后,技術(shù)已經(jīng)超越了這種范式?
帶數(shù)據(jù)的耦合函數(shù)是否可笑?
面向?qū)ο缶幊痰闹饕枷敕浅:唵危簢L試將一個程序分解為功能強大的整體。隨之而來的是,將數(shù)據(jù)片段和僅在相關數(shù)據(jù)上使用的那些函數(shù)耦合在一起。
請注意,這僅涵蓋封裝的概念。也就是說,位于對象內(nèi)部的數(shù)據(jù)和函數(shù)對于外部是不可見的,一個人只能通過消息(通常稱為getter和setter函數(shù))與對象的內(nèi)容進行交互。
繼承和多態(tài)并沒有包含在最初的想法中,但是對于當今的面向?qū)ο缶幊潭?,這是必需的。繼承基本上意味著開發(fā)人員可以定義具有其父類具有的所有屬性的子類,直到1976年——面向?qū)ο蟮某绦蛟O計概念問世十年后,才將其引入。
十年后,多態(tài)進入了面向?qū)ο蟮某绦蛟O計。從根本上講,這意味著方法或?qū)ο罂梢杂米髌渌椒ǖ哪0?。從某種意義上說,這是繼承的概括,因為并非原始方法或?qū)ο蟮乃袑傩远夹枰獋鬏斀o新實體;相反,可以選擇覆蓋屬性。
多態(tài)的特殊之處在于,即使兩個實體在源代碼中相互依賴,被調(diào)用實體的工作方式也更像插件。這使開發(fā)人員的工作更加輕松,他們不必再擔心運行時的依賴關系。
值得一提的是,繼承和多態(tài)性并不是面向?qū)ο缶幊趟氂械?。真正的區(qū)別在于封裝數(shù)據(jù)及其所屬的方法。在那個計算資源比今天稀缺得多的時代,這是一個天才般的想法。面向?qū)ο蟮木幊滩⒉豢尚?,它使編碼變得容易得多。
圖源:unsplash
面向?qū)ο缶幊讨械奈宕髥栴}
面向?qū)ο缶幊桃粏柺辣愀淖兞碎_發(fā)人員查看代碼的方式。在1980年代以前,面向過程編程通常以機器為中心,開發(fā)人員需要非常了解計算機如何工作才能編寫好的代碼。
通過封裝數(shù)據(jù)和方法,面向?qū)ο蟮木幊淌管浖_發(fā)更加以人為中心。與人類的直覺相符,方法drive()屬于數(shù)據(jù)組 car,但不屬于teddybear組。當繼承產(chǎn)生時,這也很直觀。Hyundai是car的一個子類,并且具有相同的屬性,但PooTheBear卻不是,這是完全合理的。
這聽起來像是一臺強大的機器。但問題在于,只懂面向?qū)ο蟠a的程序員將會用這種思維方式思考他們所做的一切。就像人們到處看到釘子一樣,因為他們只有錘子。正如我們將在下面看到的那樣,當你的工具箱只有錘子時,可能會導致致命的問題。
1. 大猩猩叢林香蕉問題
如果你正在設置一個新程序,并且正在考慮設計一個新類。你可能會回想起為另一個項目創(chuàng)建的簡潔的小類,并且意識到這對當前正在嘗試的工作非常適合。沒問題!可以將舊項目中的類重用于新項目。
除了該類實際上可能是另一個類的子類之外,因此現(xiàn)在還需要把父類包括在內(nèi)。然后你意識到父類也依賴于其他類,并且最終包含了代碼堆。
Erlang的創(chuàng)建者Joe Armstrong的這句話非常著名:“面向?qū)ο缶幊陶Z言的問題在于,它們具有隨身攜帶的所有隱式環(huán)境。你想要香蕉,但是得到的是一只拿著香蕉的大猩猩和整個叢林?!?/p>
這對此方法進行了很好的說明??梢灾赜妙?,實際上,這可能是面向?qū)ο缶幊痰闹饕獌?yōu)點。但不要走極端,有時最好編寫一個新類,而不是為了寫重復代碼而添加大量依賴項。要靈活變通,不要死板地遵從某個范式。
圖源:unsplash
2. 脆弱的基類問題
如果已經(jīng)成功地將另一個項目中的類重用于新代碼,那么基類會發(fā)生怎樣的變化?
它可能會破壞整個代碼,而你甚至可能都沒有碰過它。也許有一天你手上的項目熠熠生輝,而第二天卻被打回原形,因為有人更改了基類中的一個細微細節(jié),而該細節(jié)最終對項目至關重要。
使用繼承的次數(shù)越多,潛在的維護工作就越多。因此,即使在短期內(nèi)重用代碼似乎非常有效,但從長遠來看,它可能會帶來很大的代價。
3. 鉆石問題
繼承是一件可愛的小事,可以在其中繼承一類的屬性并將其轉(zhuǎn)移給其他類。但該如何組合兩個不同類的屬性?
這也許做不到,至少沒辦法以簡潔的方式做到,例如Copier類。(筆者從Charles Scalfani的熱門文章《再見,面向?qū)ο蟮木幊獭分薪栌昧诉@個示例以及有關此處出現(xiàn)的問題的一些信息。)復印機掃描文檔的內(nèi)容并將其打印在空白紙上,它應該是Scanner還是Printer的子類?
根本沒有好的答案。即使這個問題不會破壞代碼,但它經(jīng)常出現(xiàn)足以令人沮喪。
4. 層次問題
在鉆石問題中,問的是Copier是哪個類的子類。但其實我話沒說完,有一個簡單的解決方案。假設Copier 是父類,而Scanner 和Printer是僅繼承屬性子集的子類。
這就變得很簡單。但如果Copier只是黑白復印,而Printer還可以彩色打印怎么辦?從這個意義上說,打印機不是包括復印機的嗎?如果打印機連接到WiFi但復印機沒有連接怎么辦?
在類上堆積的屬性越多,建立適當?shù)膶哟谓Y(jié)構(gòu)就越困難。確實,在處理屬性集群時,其中Copier共享了Printer的部分但不是全部屬性,反之亦然。而且,如果嘗試將其置于層次結(jié)構(gòu)中,并且是一個大型復雜項目,則可能會導致混亂。不要混淆層次結(jié)構(gòu),否則可能會陷入混亂。
圖源:unsplash
5. 參考問題
有人也許會說那么我們將進行沒有層次結(jié)構(gòu)的面向?qū)ο缶幊獭F鋵嵪喾?,我們可以使用屬性集群,并根?jù)需要繼承、擴展或覆蓋屬性。這會有些混亂,但這將是對當前問題的準確表現(xiàn)。
還有一個問題。封裝的全部目的是使數(shù)據(jù)片段彼此之間保持安全,從而使計算效率更高。沒有嚴格的層次結(jié)構(gòu),這是行不通的。
如果一個對象A通過與另一個對象B交互來覆蓋層次結(jié)構(gòu),會發(fā)生什么?A與B的關系并不重要,除了B不是直接的父類。然后,A必須包含對B的私有引用,否則,將無法交互。但是,如果A包含B的子代也具有的信息,則可以在多個位置修改該信息。因此,有關B的信息已不再安全,并且封裝被破壞。
盡管許多面向?qū)ο蟮某绦騿T都使用這種架構(gòu)來構(gòu)建程序,但這并不是面向?qū)ο蟮木幊?,只是一團糟。
單一范式的危險
這五個問題的共同點是它們在不是最佳解決方案的地方實現(xiàn)了繼承。由于繼承甚至沒有包含在面向?qū)ο缶幊痰脑夹问街校虼斯P者不會將這些問題稱為面向?qū)ο蠊逃械膯栴},它們只是太過教條式的例子。
但是,不僅面向?qū)ο蟮木幊炭赡軙豢浯?。在純函?shù)式編程中,處理用戶輸入或在屏幕上打印消息極為困難。出于這些目的,面向?qū)ο蠡蜻^程編程要好得多。
仍然有一些開發(fā)人員嘗試將這些東西實現(xiàn)為純函數(shù),并將其代碼分解為數(shù)十行,沒人能理解。使用另一種范式,他們可以輕松地將代碼簡化為幾行可讀的代碼。
范式有點像宗教,它們都具有一定的合理性,耶穌、穆罕默德和佛陀說了一些很酷的話。但是,如果一直遵循教條,可能最終會使自己和周圍人的生活痛苦不堪。編程范式也是如此。毫無疑問,函數(shù)式編程正逐漸受到人們的歡迎,而在過去的幾年中,面向?qū)ο蟮木幊淘獾搅艘恍﹪绤柕呐u。
了解新的編程范式并在適當?shù)臅r候使用它們是有意義的。如果面向?qū)ο缶幊淌鞘归_發(fā)人員無論走到哪里都能看到釘子的錘子,那是把錘子扔出窗戶的原因嗎?不是。你在工具箱中添加了一把螺絲刀,也許是一把刀或一把剪刀,你不過是根據(jù)當前問題選擇工具。
函數(shù)式編程和面向?qū)ο缶幊痰某绦騿T都不要像對待宗教那樣對待編程范式。它們是工具,都可以在某處使用,所使用的內(nèi)容僅取決于待解決的問題。
一個大問題:我們正處于一場新革命的風口浪尖上嗎?
圖源:unsplash
歸根結(jié)底,關于函數(shù)式編程和面向?qū)ο缶幊痰臓幷?相當激烈)可以歸結(jié)為這一點:是否可以邁入面向?qū)ο缶幊虝r代的盡頭?
函數(shù)式編程通常是更有效的選擇,越來越多的問題出現(xiàn)。如數(shù)據(jù)分析、機器學習和并行編程,對這些領域的投入越多,就會越喜歡函數(shù)式編程。但看看現(xiàn)狀,有十多種面向?qū)ο缶幊痰某绦騿T提供的產(chǎn)品,還有一種針對函數(shù)式編碼器的產(chǎn)品。這并不意味著你不會喜歡這份工作,如今,函數(shù)式編程開發(fā)人員仍然非常稀缺。
最有可能的情況是,面向?qū)ο蟮木幊虒⒗^續(xù)存在十年左右。函數(shù)式編程當然會越來越受歡迎,但這并不意味著應該放棄面向?qū)ο缶幊獭0衙嫦驅(qū)ο缶幊套鳛楸A艏寄苋匀环浅S袃?yōu)勢。
因此,在接下來的幾年中,不要將面向?qū)ο蟮木幊虂G到工具箱外,但是請確保它不是你唯一的工具。
網(wǎng)站名稱:面向?qū)ο蟪绦蛟O計大行其道幾十年后,已經(jīng)在面臨淘汰?
當前網(wǎng)址:http://m.fisionsoft.com.cn/article/ccdpeds.html


咨詢
建站咨詢
