思考物件導向(1)物件導向與封裝 - iThome

文章推薦指數: 80 %
投票人數:10人

封裝封裝(Encapsulation)的目的,是將程式碼切割成許多模組(Module),使各模組之間的關連性降到最低,這麼一來比較不會產生「牽一髮而動全身」的狀況 ... 移至主內容 文/蔡學鏞 | 2007-10-24發表 十多年前讀大學時,我對於OO(Object-Orientation,物件導向)興致正濃,看了不少OO的書,有外文書,也有中文書。

其中,中文書為了幫助讀者理解,都會用現實生活中的物件做比擬,比方說:哺乳動物、交通工具,我記得我讀過的一個範例中提到:「斑馬」繼承自「馬」。

學習OO的重點:封裝、繼承、多型 在工研院當實習生時,老闆要我報告OO,於是我舉了書上的例子,當老闆聽到我宣稱「斑馬繼承自馬」時,他開玩笑地說:「那麼馬子(女朋友)應該也是繼承自馬。

」我深受羞辱,感覺被IT中文書荼毒了。

OO的三大基礎是封裝、繼承、多型。

用現實生活的物件做OO解說上的比擬,通常不會太恰當,因為只能解釋封裝和繼承,卻無法解釋多型。

而多型卻是OO真正的重點,也是學習OO的門檻。

沒有解釋多型,就等於小學而大遺。

對於OO,比較恰當的例子是「形狀」,一來容易理解,二來適合同時解說封裝、繼承、多型。

我認為OO的書不用看太多,只要看BertrandMeyer的名著《Object-OrientedSoftwareConstruction》第二版就夠了,但這本書可不薄。

封裝、繼承、多型這三者是有次序性的,沒有封裝就不可能有繼承、沒有繼承就不可能有多型。

只支援封裝的語言稱為Object-Based語言(例如傳統的VisualBasic);同時支援封裝、繼承、多型的語言才能稱為OO語言(例如.NET時代的VisualBasic)。

有沒有某個語言只支援封裝和繼承,卻不支援多型?不會有語言這麼無聊,基本上繼承往往只是一個中間過程,真正的目的是多型。

支援繼承,卻不支援多型,這是沒有意義的。

封裝 封裝(Encapsulation)的目的,是將程式碼切割成許多模組(Module),使各模組之間的關連性降到最低,這麼一來比較不會產生「牽一髮而動全身」的狀況,降低模組間相互依賴的程度,也等於是降低複雜度,讓開發與維護更容易。

事實上,沒有人用「模組」一詞來稱呼封裝的結果,而是稱為「類別」,把模組一詞做更高階的包裝用途。

因此我們應該將「類別」視為封裝的結果,把「模組」視為整個程式切割出來的許多片段。

在OO的世界,一般來說,一個程式有多個模組,一個模組內包含多個類別。

模組的概念不是OO獨具的,許多非OO語言也具有模組,但是OO的語言幾乎都具備模組,例如Java的Package;D語言的模組;而.NET更是細分成組件(Assembly)和模組,其實.NET的組件與模組都具備一般模組的概念,但程度有別(組件包含模組)。

封裝是以資料為核心,將相關的資料放在一起,把會用到這些資料的函式也放進來,等於將資料和函式放在一起。

儘管有的語言還有其它東西,例如Event、Property,但是從內部來看,這些都是函式的變形。

為了和非OO的世界做出區隔,OO也做了一些名詞上的改變,將Function(函式)改稱為Method(方法)、將Call(呼叫)改稱為Invoke(調用)。

但是新舊詞彙基本上還是通用的。

能見度 封裝的目的既然是要「降低互相依賴的程度」,就牽涉到能見度的問題:這個「類別/方法/欄位」該不該暴露給別的模組、同一個模組的不同類別、自己的「次類別」、友伴類別(FriendClass)、內部類別(InnerClass)?這就是所謂的「能見度」(Visibility)。

我們當然希望盡可能降低能見度,才能「降低互相依賴的程度」。

別人不需要知道的,就不要讓它知道,這就是所謂的「資訊隱藏」(InformationHiding)。

最該被隱藏的是資料。

極致的封裝主義者,主張所有資料一定都不可以直接被外部(包括次類別)存取。

上面提到,封裝將相關的資料和使用到這些資料的方法包成類別。

最理想的狀況是,讓資料能見度降到最低,外面完全看不見,留下的對外介面(Interface)只剩下Method。

換句話說,每個物件的Interface是一些方法的集合,完全沒有資料。

設定能見度不是一件容易的事,往往需要深思熟慮。

特別是對於設計「框架」(Framework)的人來說,能見度設定得太寬,造成資訊隱藏效果不佳,可能會帶來相當多負面效果(例如複雜度提高、程式容易出錯、非Thread-Safe……等);能見度設定得太緊,則造成效率變差、擴充程度變差(有些設計因而做不出來)。

(未完待續) 蔡學鏞-專職作家 清華大學資訊工程碩士,曾任華碩集團軟體工程師、元智大學資訊系講師、美商歐萊禮出版社技術編輯、臺灣微軟特約專欄作家。

相關閱讀: 思考物件導向(2)繼承與其階段性任務 思考物件導向(3)從多型看物件導向的真面目 熱門新聞 微軟Azure技術長認為應以Rust代替C/C++開發專案 2022-09-20 Chrome與Edge中的拼字檢查功能可能外洩用戶密碼 2022-09-19 Uber疑似被駭,內部多項系統遭取得權限 2022-09-19 以太坊合併後,GPU挖礦已幾乎無利可圖 2022-09-19 全家史上最大規模POS改造,不只砸上億導混合雲,雙模式三大設計一機通吃大小店種和戶外擺攤 2022-09-15 【資安週報】2022年9月12日到9月16日 2022-09-18 星巴克22萬新加坡顧客資料遭駭客公開兜售 2022-09-19 與Nvidia關係決裂?EVGA退出顯示卡市場 2022-09-19 Advertisement 2022iThome鐵人賽 專題報導 iThome2022資安大調查(下) iThome2022資安大調查(上) 【iThome2022CIO大調查(下)】各產業數位轉型加速,IT大步邁向雲原生 分散式RAID躍居主流儲存應用 【iThome2022CIO大調查(中)】企業IT新戰力 更多專題報導



請為這篇文章評分?