面向對象編程(OOP)並沒有消亡。但與過去相比,它確實沒有那麼普及了。在 90 年代時,有很多面向對象編程相關的教科書和計算機科學課程。它就是「流行趨勢」。然而,隨著時間的流逝,人們開始意識到,嚴格的面向對象方法會帶來很多問題。這些問題往往會使代碼更複雜、更難以理解且更難以測試。
在 90 年代時,有很多面向對象編程相關的教科書和計算機科學課程。它就是「流行趨勢」,是計算機的下一個浪潮。如果沒有以這種風格編程,那麼就是一個糟糕的程式設計師,或者至少落後於潮流。
當時,計算機科學(CS)專業的學生學習 OOP 的方法非常嚴格和教條。不僅鼓勵實踐者以對象和類的形式來構建應用程式,甚至還要求他們從對象和類的角度來考慮問題空間,這種實踐方法被稱為「面向對象的分析和設計」。
然而,隨著時間的流逝,人們開始意識到,嚴格的面向對象方法會帶來很多問題。這些問題往往會使代碼更複雜、更難以理解且更難以測試。
事實證明,OOP 更適合某些特定的問題領域。例如,OOP 仍然是構建用戶界面(窗口和按鈕)最自然的方式 。但是,試圖將面向對象技術應用於關係資料庫一直是一場災難。
以下是我觀察到的一些問題。
「鴨嘴獸」效應
現實世界並不總是能被整齊地劃分成具有明確屬性定義的類別。例如,假設我們創建了一個代表動物王國的類層次結構。該類層次結構中既包含爬行動物(冷血、有鱗片、產卵等等),又包含哺乳動物 (恆溫、有毛、生育等等),還包含鳥類、兩棲動物、無脊椎動物等等。
然而,對於鴨嘴獸,它似乎不屬於我們上述定義的任何類別。我們要做什麼呢?我們是創建一個全新的類別,還是重新考慮整個分類方案呢?就工作量和程序複雜性而言,這兩種方法都會產生顯著的成本。
深層次結構
我記得當我還在谷歌工作的時候,有一個 JavaScript 庫 goog.ui,它可以用於創建基於 Web 的用戶界面。以下是這個庫中某個 UI 組件的繼承層次結構:
class ToolbarColorMenuButton* inherits from ColorMenuButton * inherits from MenuButton * inherits from Button * inherits from Control * inherits from Component * inherits from EventTarget * inherits from Disposable * inherits from Object九層的類繼承好多。然而,情況還會變得更糟糕。
在這些高層類中,有許多都被只與少數子類相關的方法和屬性「汙染」了。例如,「Control」類有 90 多個方法。它具有設置狀態的方法,即使特定的子類是無狀態的;它有添加和刪除子元素的方法,即使控制項包含子元素也沒有任何意義。
造成這種複雜性的一個重要原因是,該庫的作者試圖通過將組件放到類層次結構的不同位置來組織組件的不同功能 ,例如,組件是按鈕還是滑塊,或者組件是否有顏色 。
但實際上,這些不同功能的組件彼此之間無關。咖啡杯是紅色的,和它是用陶瓷製成的,基本上是獨立的屬性。將紅色咖啡杯歸入「紅色物品」的類別,並不比將其歸入「陶瓷製品」甚至「家居用品」的類別更正確。任何一個都是任意選擇的,因為類別是精神和社會的結構。
在谷歌工作的最後幾年裡,為了替代 goog.ui,我創建了一個名為「Quantum Wiz」的新用戶界面工具包。我們採用的規則之一(以典型的谷歌風格,寫成方程式)是:
組合 > 繼承簡單地說,這句話的意思是:
「更傾向於使用組合......
點擊了解更多,查看全文