成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面向對象編程是計算機科學的最大錯誤

開發 前端
C ++和Java可能是計算機科學中最嚴重的錯誤。OOP的創建者艾倫·凱(Alan Kay)和許多其他著名的計算機科學家都對兩者都提出了嚴厲的批評。然而,C ++和Java為最臭名昭著的編程范例-現代OOP鋪平了道路。

C ++和Java可能是計算機科學中最嚴重的錯誤。OOP的創建者艾倫·凱(Alan Kay)和許多其他著名的計算機科學家都對兩者都提出了嚴厲的批評。然而,C ++和Java為最臭名昭著的編程范例-現代OOP鋪平了道路。

它的普及是非常不幸的,它對現代經濟造成了巨大破壞,造成了數萬億美元的間接損失。OOP導致數千人喪生。在過去的三十年中,沒有任何一個行業因潛在的OO危機而受到影響。

為什么OOP如此危險?讓我們找出答案。

[[376179]]

想象一下,帶您的家人在一個美麗的星期天下午乘車兜風。外面很好,陽光明媚。所有人都進入了汽車,行駛了與上百萬次完全相同的高速公路。

但是這次卻有所不同–即使您放開油門踏板,汽車仍會繼續不受控制地加速行駛。剎車也不起作用,似乎它們失去了動力。為了挽救局勢,您緊急拉了緊急制動器。在您的汽車撞到路邊的路堤之前,這會在道路上留下150英尺長的防滑痕跡。

聽起來像一場噩夢?但這正是2007年9月讓·布克特(Jean Bookout)駕駛豐田凱美瑞(Camry)時發生的事情。這不是唯一的此類事件。這是與所謂的"意外加速"有關的眾多事件之一,該事件困擾了豐田汽車十多年,造成近100人死亡。汽車制造商很快就將手指對準了"粘性踏板",駕駛員失誤甚至地板墊。但是,一些專家長期以來一直懷疑有問題的軟件可能正在發揮作用。

為了解決這個問題,美國宇航局的軟件專家已被征召入伍,一無所獲。僅僅幾年后,在對Bookout事件進行調查的過程中,真正的罪魁禍首是由另一個軟件專家團隊發現的。他們花了將近18個月的時間來研究豐田代碼。他們將Toyota代碼庫描述為"意大利面條代碼",這是一種用于纏結代碼的程序員術語。

軟件專家已經演示了超過1000萬種豐田軟件導致意外加速的方法。最終,豐田被迫召回了超過900萬輛汽車,并支付了超過30億美元的和解費和罰款。

[[376180]]

意大利面條代碼有問題嗎?

某些軟件故障造成的100條生命是太多了。真正令人恐懼的是,豐田代碼的問題不是唯一的。

兩架波音737 Max飛機墜毀,造成346人死亡,損失超過600億美元。都是由于軟件錯誤,由意大利細面條代碼引起的100%的確定性。

在全球范圍內,意大利面條式代碼困擾著太多的代碼庫。機載計算機,醫療設備,在核電站上運行的代碼。

程序代碼不是為機器編寫的,而是為人類編寫的。正如馬丁·福勒(Martin Fowler)所說:"任何傻瓜都可以編寫計算機可以理解的代碼。好的程序員編寫人類可以理解的代碼。"

如果代碼沒有運行,則說明它已損壞。但是,如果人們不理解該代碼,那么它將被破壞。不久。

讓我們快速繞道,談論人的大腦。人腦是世界上最強大的機器。但是,它有其自身的局限性。我們的工作記憶是有限的,人腦一次只能思考5件事。這意味著,程序代碼的編寫方式不應使人的大腦不知所措。

意大利面條代碼使人腦無法理解代碼庫。這產生了深遠的影響-無法看到某些變化是否會破壞其他東西。對缺陷進行詳盡的測試變得不可能。沒有人甚至不能確定這樣的系統是否正常工作。如果確實有效,那為什么還要有效呢?

是什么導致意大利面條代碼?

為什么隨著時間的流逝,代碼變成意大利面條式代碼?由于熵-宇宙中的一切最終變得混亂無序,混亂。就像電纜最終將變得混亂一樣,我們的代碼最終也將變得混亂不堪。除非有足夠的約束。

為什么我們在道路上有速度限制?是的,有些人會永遠恨他們,但它們可以防止我們墜毀甚至死亡。為什么在路上有標記?為了防止人們走錯路,防止事故發生。

在編程時,類似的方法將完全有意義。這樣的約束不應留給程序員來擺放。它們應該通過工具自動實現,或者理想情況下通過編程范例本身來實現。

為什么OOP是萬惡之源?

[[376181]]

> Photo by NeONBRAND on Unsplash

我們如何執行足夠的約束來防止代碼變成意大利面條?兩個選項-手動或自動。手動方法容易出錯,人類總是會犯錯誤。因此,自動執行此類約束是合乎邏輯的。

不幸的是,OOP并不是我們一直在尋找的解決方案。它沒有提供任何約束來幫助解決代碼糾纏問題。一個人可以精通各種OOP最佳實踐,例如依賴注入,測試驅動的開發,域驅動的設計等(確實有幫助)。但是,這些都不是由編程范例本身來強制執行的(并且不存在可以強制執行最佳實踐的此類工具)。

內置的OOP功能都無法幫助防止意大利面條式代碼-封裝只是在程序中隱藏和分散狀態,這只會使情況變得更糟。繼承增加了更多的混亂。OOP多態性再次使事情變得更加混亂-不知道程序在運行時將采用哪種確切的執行路徑沒有任何好處。特別是在涉及多個繼承級別時。

OOP進一步加劇了意粉代碼問題

缺乏適當的約束(以防止代碼變得混亂)不是OOP的唯一缺點。

在大多數面向對象的語言中,默認情況下所有內容都是通過引用共享的。有效地將一個程序變成一個龐大的全球狀態。這與OOP的原始思想直接沖突。OOP的創建者Alan Kay具有生物學背景。他想到了一種語言(Simula),可以用類似于生物細胞的方式編寫計算機程序。他希望有獨立的程序(單元)通過相互發送消息進行通信。獨立程序的狀態永遠不會與外界共享(封裝)。

艾倫·凱(Alan Kay)從未打算讓"細胞"直接進入其他細胞的內部進行更改。但這正是現代OOP中發生的事情,因為在現代OOP中,默認情況下,所有內容都是通過引用共享的。這也意味著回歸成為必然。更改程序的一部分通常會破壞其他地方的功能(這在其他編程范例(如功能編程)中很少見)。

我們可以清楚地看到,現代OOP從根本上來說是有缺陷的。每天都會在工作中折磨您的"怪物"。而且它也會在晚上困擾您。

讓我們談談可預測性

[[376182]]

> Photo by samsommer on Unsplash

意大利面條代碼是個大問題。面向對象的代碼特別容易意大利化。

意大利面條代碼使軟件無法維護。但這只是問題的一部分。我們還希望軟件可靠。但是,這還不夠,軟件(或與此相關的任何其他系統)可以預見。

任何系統的用戶無論如何都應具有相同的可預測的體驗。踩下汽車油門踏板始終會導致汽車加速。踩剎車總是會導致汽車減速。用計算機科學術語來說,我們希望汽車具有確定性。

汽車表現出隨機行為是非常不希望的,例如加速器無法加速或制動器未能制動(豐田問題)。即使此類問題僅在一萬億次發生一次。

然而,大多數軟件工程師的心態是"該軟件應足以讓我們的客戶繼續使用它"。我們真的可以做得更好嗎?當然可以,我們應該做得更好!最好的起點是解決我們程序的不確定性。

非確定性101

在計算機科學中,與確定性算法相反,非確定性算法是一種即使對于相同的輸入也可以在不同的運行中表現出不同行為的算法。

—有關非確定性算法的維基百科文章

如果上述Wikipedia上關于非確定性的說法對您來說聽起來不太好,那是因為非確定性沒有任何好處。讓我們看一下僅調用函數的代碼示例:

我們不知道該函數的功能,但是在給定相同輸入的情況下,該函數似乎總是返回相同的輸出?,F在,讓我們看一下另一個示例,該示例調用另一個函數computeb:

這次,函數為同一輸入返回了不同的值。兩者有什么區別?給定相同的輸入,前一個函數總是產生相同的輸出,就像數學中的函數一樣。換句話說,功能是確定性的。后一種功能可能會產生期望值,但這不能保證。換句話說,函數是不確定的。

是什么使函數具有確定性或不確定性?

  • 不依賴外部狀態的功能是100%確定性的。
  • 僅調用其他確定性函數的函數是確定性的。

在上面的示例中,computea是確定性的,并且在給定相同輸入的情況下,將始終提供相同的輸出。因為其輸出僅取決于其參數x。

另一方面,computeb是不確定性的,因為它調用了另一個不確定性函數Math.random()。我們如何知道Math.random()是不確定的?在內部,它取決于系統時間(外部狀態)來計算隨機值。它還不帶任何參數-依賴于外部狀態的函數的無用贈品。

確定性與可預測性有什么關系?確定性代碼是可預測的代碼。非確定性代碼是不可預測的代碼。

從確定論到非確定論

[[376183]]

> Photo by Annie Spratt on Unsplash

讓我們看一下附加功能:

我們始終可以確定,給定(2,2)的輸入,結果將始終等于4。我們怎么能這么確定?在大多數編程語言中,加法運算是在硬件上實現的,換句話說,CPU負責計算結果始終保持不變。除非我們要處理浮點數的比較,否則(但這是另一回事,與不確定性問題無關)?,F在,讓我們關注整數。硬件非??煽?,可以安全地假定加法結果始終正確。

現在,讓我們將值2裝箱:到目前為止,功能是確定的!

現在,我們對函數主體進行一些小的更改:

  • 發生了什么?突然函數的結果不再可預測!第一次運行良好,但是在隨后的每次運行中,其結果開始變得越來越不可預測。換句話說,該功能不再是確定性的。
  • 為什么突然變成不確定的?該函數通過修改超出其范圍的值而引起了副作用。

讓我們回顧一下

確定性程序可確保2 + 2 == 4。換句話說,給定輸入(2,2),函數add始終應得到4的輸出。無論您調用該函數多少次,無論您是否并行調用該函數,以及該函數外部的外觀如何。

非確定性程序正好相反。在大多數情況下,對add(2,2)的調用將返回4。但是有時,該函數可能會返回3、5甚至1004。不確定性在程序中是非常不可取的,我希望您現在可以理解為什么。

非確定性代碼的后果是什么?軟件缺陷或通常被稱為"錯誤"的缺陷。錯誤使開發人員浪費了寶貴的調試時間,并且如果將其投入生產,則會大大降低客戶體驗。

為了使我們的程序更可靠,我們應該首先解決不確定性問題。

副作用

[[376184]]

> Photo by Igor Yemelianov on Unsplash

這給我們帶來了副作用的問題。

什么是副作用?如果您因頭痛而服用藥物,但這種藥物使您惡心,那么惡心是一種副作用。簡而言之,這是不可取的。

想象一下,您已經購買了一個計算器。您將其帶回家,開始使用它,然后突然意識到這不是一個簡單的計算器。您自己有了一個扭曲的計算器!您輸入10 * 11,它將輸出110作為輸出,但同時還會向您大喊一百和十。這是一個副作用。接下來,輸入41 + 1,它打印42,并注釋" 42,生命的意義"。副作用也一樣!您感到困惑,然后開始與您想訂購披薩的重要對象進行交談。計算器會偷聽對話,大聲說"好",然后下達比薩訂單。副作用也一樣!

讓我們回到加法功能:

是的,該函數執行了預期的操作,將a添加到b。但是,這也會帶來副作用。對a.value + = b.value的調用導致對象a發生更改。函數參數a引用對象2,因此two.value不再等于2。第一次調用后,其值變為4,第二次調用后,其值為6,依此類推。

純度

[[376185]]

> Photo by yann bervas on Unsplash

在討論了確定性和副作用之后,我們準備討論純度。純函數是既具有確定性又沒有副作用的函數。

再一次,確定性意味著可預測的—給定相同的輸入,該函數將始終返回相同的結果。而且沒有副作用意味著該函數除了返回值外什么也不做。這樣的功能是純粹的。

純函數有什么好處?正如我已經說過的,它們是可以預測的。這使得它們非常易于測試(無需模擬和存根)。關于純函數的推理很容易-與OOP不同,無需牢記整個應用程序狀態。您只需要擔心當前正在使用的功能。

純函數可以輕松組成(因為它們不會在其范圍之外進行任何更改)。純函數對于并發非常有用,因為函數之間沒有共享狀態。重構純函數是純粹的樂趣-只需復制和粘貼,無需復雜的IDE工具。

簡而言之,純函數將歡樂帶回到編程中。

面向對象編程的純度如何?

為了舉例說明,我們來討論一下OOP的兩個功能:getter和setter。

吸氣劑的結果取決于外部狀態-對象狀態。多次調用getter可能會導致不同的輸出,具體取決于系統的狀態。這使得吸氣劑本質上是不確定的。

現在,二傳手。設置器用于更改對象的狀態,從而使它們固有地具有副作用。

這意味著OOP中的所有方法(除了靜態方法之外)都是不確定性的,或者會帶來副作用,但每種方法都不是好方法。因此,面向對象編程不是純粹的東西,它與pure完全相反。

有一個銀彈。

但是我們很少有人敢嘗試。

[[376186]]

> Photo by Mohamed Nohassi on Unsplash

無知并不過分,因為不愿學習。

本杰明·富蘭克林

在令人沮喪的軟件故障世界中,存在著一線希望,這將解決大多數(如果不是全部)問題。真正的銀彈。但是只有當您愿意學習和應用時,大多數人才不會。

銀彈的定義是什么?可以用來解決我們所有問題的東西。數學是靈丹妙藥嗎?如果有的話,它幾乎是銀彈。

我們要歸功于成千上萬的千百年來為我們提供數學知識的聰明才智的男女。歐幾里得,畢達哥拉斯,阿基米德,艾薩克·牛頓,萊昂哈德·歐拉,阿隆佐教堂等等。

如果不確定性(即不可預測)的東西成為現代科學的支柱,您認為我們的世界將會走多遠?可能不會很遠,我們會留在中世紀。這實際上在醫學界已經發生過-過去,沒有嚴格的試驗來證實特定治療或藥物的功效。人們依靠醫生的意見來治療自己的健康問題(不幸的是,這種問題在俄羅斯等國家仍然存在)。過去,無效的技術(例如放血)已廣為流行。像砷一樣不安全的東西被廣泛使用。

不幸的是,當今的軟件行業與過去的醫學太相似了。它不是基于堅實的基礎。取而代之的是,現代軟件行業主要基于脆弱的搖擺不定的基礎,即所謂的面向對象編程。如果人類的生活直接取決于軟件,那么就像放血和其他不安全的做法一樣,面向對象的操作將早已消失并被遺忘。

堅實的基礎

[[376187]]

> Photo by Zoltan Tasi on Unsplash

有其他選擇嗎?在編程世界中,我們可以擁有像數學一樣可靠的東西嗎?是!許多數學概念直接轉化為編程,并奠定了稱為函數式編程的基礎。

函數式編程是編程的數學-一個極其牢固和健壯的基礎,可用于構建可靠和健壯的程序。是什么使它如此強大?它基于數學,尤其是Lambda微積分。

為了進行比較,現代OOP是基于什么?是的,正確的Alan Kay OOP是基于生物細胞的。但是,現代的Java / C#OOP是基于一組荒謬的思想(例如類,繼承和封裝)的,它沒有Alan Kay的天才發明的原始思想。其余的只是一組創可貼,以解決其劣等思想的缺點。

函數編程呢?它的核心組成部分是一個函數,在大多數情況下是一個純函數。純函數是確定性的,這使它們可預測。這意味著由純函數組成的程序將是可預測的。他們會永遠沒有錯誤嗎?不會,但是如果程序中存在錯誤,也將是確定性的-對于相同的輸入始終會發生相同的錯誤,因此更易于修復。

我怎么到這里了?

過去,在過程/功能出現之前,goto語句已廣泛用于編程語言中。goto語句僅允許程序在執行過程中跳至代碼的任何部分。這使得開發人員很難回答"我如何到達執行點?"這一問題。是的,這已導致大量錯誤。

如今,一個非常相似的問題正在發生。僅在這一次,困難的問題是"我如何到達此狀態"而不是"我如何到達此執行點"。

OOP(通常是命令式編程)回答"我如何達到這種狀態?"的問題。硬。在OOP中,所有內容均通過引用傳遞。從技術上講,這意味著任何對象都可以被任何其他對象所突變(OOP對此沒有任何約束)。封裝根本沒有幫助-調用一種方法來更改某些對象字段并不比直接對其進行更改更好。這意味著程序很快就會變成一堆依賴關系,從而使整個程序成為全局狀態的一大塊。

有什么解決方案可以使我們停止問"我如何到達此狀態"?您可能已經猜到了函數式編程。

過去,許多人都拒絕了停止使用goto的建議,就像今天的許多人都反對函數式編程和不可變狀態的想法一樣。

但是等等,意大利面條代碼呢?

[[376188]]

> Photo by Andrea Piacquadio from Pexels

在OOP中,"優先于繼承而不是繼承"被認為是最佳實踐。從理論上講,此類最佳做法應有助于意大利面條式代碼。不幸的是,這僅僅是"最佳實踐"。面向對象的編程范例本身對執行此類最佳實踐沒有任何限制。您的團隊中的初級開發人員必須遵循此類最佳做法,并在代碼審查中強制實施(并非總是如此)。

函數編程呢?在函數式編程中,函數組合(和分解)是構建程序的唯一方法。這意味著編程范例本身會強制執行組合。正是我們一直在尋找的東西!

函數調用其他函數,較大的函數始終由較小的函數組成。就是這樣。與OOP不同,函數式編程中的組合是自然的。此外,這使得重構等過程非常容易-只需剪切代碼,然后將其粘貼到新函數中即可。無需管理復雜的對象依賴項,也不需要復雜的工具(例如Resharper)。

可以清楚地看到,OOP是代碼組織的次等選擇。函數式編程的明顯勝利。

但是OOP和FP是互補的!

抱歉讓您失望。它們不是互補的。

面向對象編程與功能編程完全相反。說OOP和FP是互補的,就等于說放血和抗生素是互補的……是嗎?

OOP違反了許多基本的FP原則:

 

  • FP提倡純凈,而OOP提倡雜質。
  • FP代碼從根本上講是確定性的,因此是可預測的。OOP代碼本質上是不確定的,因此是不可預測的。
  • 組合在FP中是自然的,在OOP中不是自然的。
  • OOP通常導致錯誤的軟件和意大利面條代碼。FP生成可靠,可預測和可維護的軟件。
  • FP很少需要調試,而不是簡單的單元測試會更多。另一方面,OOP程序員住在調試器中。
  • OOP程序員花費大部分時間來修復錯誤。FP程序員花費大部分時間來交付結果。

最終,函數式編程是軟件界的數學。如果數學為現代科學奠定了非常堅實的基礎,那么它也可以以函數式編程的形式為我們的軟件奠定堅實的基礎。

采取行動,為時已晚

[[376189]]

> Image source: https://www.pexels.com/photo/blue-sky-161148/

OOP是一個非常大且代價非常高的錯誤。讓我們最終都承認這一點。

知道我乘坐的汽車運行的是用OOP編寫的軟件,這使我感到害怕。知道帶我和家人休假的飛機使用面向對象的代碼并不能使我感到更安全。

現在我們該采取最終行動的時候了。我們所有人都應該開始采取一些小步驟,以認識到面向對象編程的危險,并開始努力學習函數式編程。這不是一個快速的過程,至少我們需要十年才能做出轉變。我相信,在不久的將來,那些繼續使用OOP的人將被視為"恐龍",類似于今天的COBOL程序員已過時。C ++和Java將會消亡。C#將死亡。TypeScript也將很快成為歷史。

我希望您立即采取行動-如果您還沒有這樣做,請開始學習函數式編程。變得真正擅長,并廣為傳播。F#,ReasonML和Elixir都是入門的絕佳選擇。

大型軟件革命已經開始。您會加入還是落伍?

原文鏈接:https://suzdalnitski.medium.com/oop-will-make-you-suffer-846d072b4dce

 

責任編輯:趙寧寧 來源: 今日頭條
相關推薦

2021-03-07 00:47:37

開發編程科學

2013-01-09 09:27:09

面向對象計算機編程

2011-10-17 09:50:38

編程

2012-09-10 09:43:21

編程編程學習編程錯誤

2021-01-26 09:19:50

計算機數據中心故障IT服務

2019-04-30 15:14:11

數據科學家計算機

2019-09-10 12:58:03

電腦編程語言硬件

2010-07-21 16:10:25

計算機

2023-01-10 09:38:09

面向對象系統

2021-05-28 05:34:06

Golang語言編程

2013-01-10 10:05:29

編程面向對象編程

2023-07-07 10:53:08

2017-05-15 12:58:00

編程javaapl

2012-01-17 09:34:52

JavaScript

2017-04-21 09:07:39

JavaScript對象編程

2020-11-11 11:00:58

計算機程序員編程

2009-05-22 10:43:44

2018-07-06 14:12:50

計算機薪酬錢景

2010-11-17 11:31:22

Scala基礎面向對象Scala

2019-04-30 09:45:12

計算機互聯網 技術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人精品一区二 | 作爱视频免费观看 | 很黄很污的网站 | 日韩电影一区 | 极品国产视频 | 日韩在线欧美 | 中文字幕在线看 | 日本一区二区三区免费观看 | 欧美色视频免费 | 日本黄色影片在线观看 | 精品国产精品国产偷麻豆 | 亚洲高清成人在线 | 日本精品久久久一区二区三区 | 午夜爽爽爽男女免费观看影院 | 国产精品美女www爽爽爽视频 | 久久午夜精品福利一区二区 | 国产精品一区在线 | 成人夜晚看av | 在线看亚洲 | 欧美成人高清视频 | 国产精品久久99 | 欧美成人精品二区三区99精品 | 久久99国产精一区二区三区 | 国产一区免费视频 | 国产第一页在线观看 | 欧美日韩视频在线 | 亚洲精品国产a久久久久久 中文字幕一区二区三区四区五区 | 亚洲欧美久久 | 91豆花视频 | 午夜日韩精品 | 久热免费在线 | 欧美一区二区三区在线 | 国产高清视频一区二区 | 夜夜爽99久久国产综合精品女不卡 | 欧美视频日韩 | 二区欧美 | 亚洲手机在线 | 91电影| 91精品国产综合久久精品图片 | 亚洲一区二区三区免费视频 | 射久久 |