2010/12/11

翻譯:這不是物件導向程式設計啦(What OOP Isn't )by Benjamin Supnik

文章:What OOP Isn't(這不是物件導向程式設計啦)
日期:2010.12.09
作者:Benjamin Supnik
作者的部落格:The Hacks of Life


這不是物件導向程式設計啦(What OOP Isn't)


想當初,我開始上第一堂的電腦科學課程(不過在那以前,我已經自己開始寫程式有一段時間了),系上教職員正在打一場內戰,某部分人信仰著物件導向程式設計(object-oriented programming, OOP),他們相信世間萬物皆物件,物件就是王道啊,他們教授要我們學生用OOP的方式來實作鏈結串列(linked list):哇賽,每一個節點都是被完完全全封裝起來的物件!


(什麼,你有興趣知道嗎,讓我告訴你,串列大部分的編輯動作,都必須是堆疊-遞迴式(stack-recursive)──當呼叫一個節點的next時,節點要把它的'next'設定為呼叫的回傳值,讓某節點能夠'把自己切掉'。嘿嘿,聽的懂算你強,這讓那些從沒碰過鏈結串列的學生,一個頭兩個大,根本不知道到底自己在幹嘛,因為,他們在同一個時間,碰到了遞迴與鏈結串列,而寫出來的程式,結果是,執行起來有著LISP的效能,而程式碼看起來像C++的優雅,真是糟糕可怕啊。)


他們說,OOP的三大支柱是封裝、多型、繼承(encapsulation, polymorphism, inheritance),我以前已經發表文章說過為什麼最後一項通常會是個不好的概念,回想那時在學校的時光,我還沒有足夠的程式開發經驗,所以只能說,當時我們被教的東西(全部都是OOP,不論何時何地)比我一直以來在寫的程式(用物件來表示某種很大的東西,例如遊戲裡的一個角色)要難上好幾倍,寫出來的程式碼,又囉嗦也沒有特別快,現在,我有了軟體工程的經驗,我想,可以把其中問題所在更精確地描述出來。


有時,看到程式新手眼裡閃著OOP字眼,努力學會這到底在講些什麼,我會跟他們說,封裝、多型、繼承的相對重要程度大概是90%、10%、0%,OOP絕大部分的價值所在,是它提供機制與作法,可以把一段程式碼跟其他不相干的程式碼分離開來,而不會混雜在一起,而這點對大型軟體開發專案很重要,而你不可能教會大學生這一點,因為他們還沒有夠多的程式開發經驗,無法體會其中的重要性。


多型也不錯,但據我的經驗,它不像封裝那麼有用,如果你有個多型介面,有個介面就表示,它是被封裝的,但是,有許多的案例顯示,有些介面就只會用一次,而且沒有多型這項性質,粗略來講大概是90%-10%吧,所以我認為扮演舉足輕重角色的是封裝。當然,有些產品與領域比其他地方更常使用多型,WorldEditor(Laminar Research的開放原始碼場景編輯器)大部分的核心元件採用多型介面的架構,但X-Plane本身就很少。

我提出這點,因為我大概(在以後的發表文章中)會把OOP與其他技術(與軟體工程碰到的實質困難有關的)作個比較,不過OOP有一點歷史包袱,過去常常講,OOP可以讓我們變成更好的程式設計師,可以幫助我們寫出無臭蟲的程式碼,執行速度更快了,或是可以幫助差勁的程式設計人員升級成優良的,這些都被時間證明了,只不過是些天真白痴一廂情願的想法(特別是,差的程式設計師,不論給予什麼樣的技術或方法,照樣可以生產出低劣的程式碼,一大沱)。

所以,我希望幫OOP這玩意作類似如下的定義:在語言上提供好的支援來進行封裝,有時候需要有多型介面,加速撰碼。這對我來說就非常好用了!我可以僅用純C語言寫出相同的東西,但不僅需要花更多時間打字,還會讓我變成很嘮叨的人,不斷囉囉唆唆血壓上升,何苦呢?

1 comment:

  1. 瀏覽您的樹莓派文章,順道看到了這篇文章,提供下看法供參考~

    軟體設計的三大原則應該是封裝 (encapsulation)、介面 (interface)與多型 (poly-morphism)。
    至於繼承 (inheritance) 則是多型實踐的手法。

    但事實上,繼承這個字眼實在很不恰當,C++ 使用這個關鍵字造成誤導很多;所以後來 Java/C#.NET 等均改回為 擴展 (extend) 才是符合多型的原意。

    簡而言之,這三個設計原則都是基於 "變" 這個議題。
    封裝是"抑制變";介面是"包容變";多型則是為了"應變"。

    有興趣討論這些軟體設計的議題,可以另行再聊聊囉~~

    ReplyDelete