Ruby 使用手冊

物件導向思維

物件導向 (object oriented) 是個引人注意的詞彙, 把東西稱為物件導向,讓人聽起來覺得很聰明。Ruby 宣稱為物件導向程式語言,但到底「物件導向」是甚麼意思?

答案各式各樣,但重點都是一樣。先不這麼快就下結論,讓我們先想想傳統的程式設計範式 (programming paradigm)。

一般來說,程式設計遇到的問題都是要想出資料表示法 (data representation) 及在資料執行的程序 (procedure)。這種情況下,資料的性質是惰性、被動、無法自主的,完全任由龐大的程式體擺佈,而這個程式體是主動、邏輯、全能的。

這種方式的問題在於程式需要由程式員編寫,而程式員只能靠腦袋來記住大量的細節。當項目變大,程序核心也會持續成長,最終使程式員無法記住全部程式。思考出錯或打錯程式碼都會成為難以察覺的程序錯誤, 導致程序核心出現複雜而意外的運算,維護工作將會讓你手忙腳亂。傳統程式設計範式會提供指引,減少或找出程序錯誤,但最好的解決方法還是從根本作出改變。

物件導向程式設計能夠將單調而重複的邏輯工作委派予資料,把我們對資料的概念從被動轉為主動。換而言之,

上述的「機器」內部可能非常複雜,也可能非常簡單,並不能單以外部作出判斷,我們不會隨意拆開機器(除非我們非常確定設計出現問題),所以我們只需要按按開關,了解有甚麼功能可以與資料互動。機器做好後,我們就不會再去想它是如何運作了。

你可能會覺得這樣好像更麻煩,但是這種方式能夠預防各種問題。

以下範例雖然沒什麼實用價值,但也能解釋部分概念。你的車上有里程表, 可用來計算按下重設鍵後所行駛的路程。我們可如何將這編寫為程式語言呢?在 C 中,里程表只是個數值變數,很可能就是浮點數 (float)。程式會慢慢遞增變數,有時可能會將變數重設為零。這樣的程式有甚麼問題嗎?任何非預期的臭蟲(Bug)程式都可能將此變數設定成錯誤值。使用過 C 的人都知道,要找出錯誤可能要花上數小時甚至數天,而最後才發現那個錯誤原來很無稽。(找到錯誤的那一刻,才讓人恍然大悟。)

從物件導向角度看來,這個程式也有問題。程式員設計里程表時,首先想到的不是「哪些資料類型與這個最為類似?」,而是「這程式到底會怎麼運作?」其中的差別就會形成嚴重的問題。應該花點時間決定里程表的用處,以及人們會如何使用。我們要製作能夠操作小機器,能夠遞增數值、重設、顯示數值,就這些功能而已。

我們不會讓里程表有機會加入任意值, 因為里程表根本不需要這個功能。里程表只具有幾項功能而已,這些功能我們已經賦予了它。因此,如果程式錯誤地嘗試加入其他數值(車輛氣候控制的溫度)至里程表中,就會立即指出哪裡出現問題。我們知道運行程式期間,(或編譯 (compiling),視乎程式語言而定),我們無法在里程表中加入任意值。這可能不是非常清楚,但仍是清晰合理。這不能預防錯誤發生, 但能夠幫我們迅速地找出問題。這就是物件導向程式設計幫我們節省時間的其中一項方式。

接著讓我們進一步抽象化以上的範例,因為建立一間製造機器的工廠,跟製造一個機器其實同樣簡單。因此我們並不是直接建立一個里程表,而是建立一個可以製造里程表的工廠,利用一個模子(pattern)來生產任意個里程表。這個模子(pattern)樣式(或是你想要稱為里程表工廠)我們稱作類別 (class),而從樣式產生的個別里程表(或工廠製造的里程表)我們稱作物件 (object)。大部分物件導向語言要求先定義類別 (class),才能開始新的物件(object),但 Ruby 並無這種限制。

要注意的是,使用物件導向語言不會保證有好的物件導向設計。確實任何語言的程式碼都有可能編寫得不清不楚、凌亂、毫不周詳⋯⋯ Ruby 的優點在於(特別是相對 C++ 而言)能夠自然地編寫物件導向程式,即使編寫小程式,也不用花費精力來解決零亂的程式碼。本手冊之後會討論如何利用 Ruby 達成目標,下一節將是「開關與功能」(物件方法),然後是「工廠」(類別)。你還在看吧?

Copyright (c) 2005-2008 Mark Slagell,中文翻譯 Ruby Taiwan 社群

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.

A copy of the license is included in the section entitled "GNU Free Documentation License."