前言
接上節(jié)面向?qū)ο笤O(shè)計(jì)隨想.
凡入派者, 必遵其規(guī).
既然我們加入"面向?qū)ο?一黨, 必然要信奉其中的一些價值觀(心法):
- 萬物皆對象, 對象皆有類
- 關(guān)系驅(qū)動世界發(fā)展
- 萬物唯變不變
萬物皆對象, 對象皆有類
在面向?qū)ο蟮氖澜缋? 所有的一切都是可以抽象成一個對象, 例如玫瑰花, 銀杏樹, 啄木鳥, 東北虎, 所有東西我們都可以抽象成: 是什么, 有什么, 能做什么; 然后進(jìn)一步, 我們可以再抽象, 再封裝, 進(jìn)而歸結(jié)為類 -- 花木鳥獸.
抽象是從我們看事物的視角, 幫助我們將自己從繁雜的細(xì)節(jié)中解脫岀來, 在更高的層次去理解一個東西的一種思維方式.
封裝是從事務(wù)本身的視角, 盡量對外隱藏細(xì)節(jié), 只暴露自己需要暴露的能力. 例如手機(jī), 只要對外暴露打電話的能力, 而無需讓外界知道具體打電話這個動作的細(xì)節(jié)是怎樣完成的.
這兩個面向?qū)ο筇匦允俏覀兝斫饷嫦驅(qū)ο蟮幕A(chǔ), 我們在把萬物映射到我們的代碼世界時, 無處不在使用這兩個特性.
關(guān)系驅(qū)動世界
當(dāng)我們試圖將某個事物單獨(dú)挑出來時, 我們發(fā)現(xiàn)它與宇宙中的其他事物是息息相關(guān)的.
-- 約翰.謬爾(美國作家), 1911, <<山間夏日>>
世間沒有任何一個東西可以是獨(dú)立于其他事物而存在的, 同樣映射到我們的代碼世界, 在將事物抽象成對象/類之后, 我們要做的就是尋找之間的關(guān)系.
看上圖, 我們可以找到很多關(guān)系:
- 類與子類之間的繼承關(guān)系.
- 方法與方法之間的重載/重寫關(guān)系.
- 類與對象之間的抽象-具體關(guān)系
- 對象/類之間的各種組合依賴關(guān)聯(lián)...關(guān)系
繼承與多態(tài)
其中關(guān)于類, 有一個基本關(guān)系, 那就是繼承 -- 子承父業(yè), 發(fā)揚(yáng)光大.
繼承可以我們從原有同類事物中獲得一些基本能力, 同時可以做擴(kuò)展.
一般來說, 繼承岀來的子類和父類之間的關(guān)系是特殊(特例)和一般(抽象)之間的關(guān)系. 例如鳥是動物的一類, 它具有動物的特征和能力, 也會有自己特有的特征和能力:
另外, 如果細(xì)心的話, 大家可以看到我們在鳥這個子類里面還對父類動物的"活動()"方法做了重寫. 這個覆蓋重寫給了我們的繼承關(guān)系一種更高端的能力 --- (運(yùn)行時)多態(tài). 所謂多態(tài), 簡單理解就是動態(tài)決策. 一個事物有多種形態(tài)的存在, 都可以對某一個特定事件產(chǎn)生響應(yīng), 根據(jù)運(yùn)行時的具體情況來隨機(jī)應(yīng)變.
這樣做有什么好處呢? 最大的好處就是分離了"能做什么"和"具體怎么做", 也就是將接口和實(shí)現(xiàn)分離了. 讓我們的程序有了很大的擴(kuò)展性, 實(shí)際上很多設(shè)計(jì)模式也都是基于多態(tài)這個面向?qū)ο筇匦猿恋淼?
另外還有一種編譯時多態(tài), 就是同一個類中方法的重載 --- 方法名相同, 傳入?yún)?shù)不一樣, 做的事情不一樣. (見人說人話, 見鬼說鬼話).
六大類關(guān)系
當(dāng)然我們的類關(guān)系, 除了繼承, 還有很多其他的關(guān)系形式, 多姿多彩的關(guān)系才能構(gòu)建我們五彩斑斕的世界嘛.
當(dāng)我們在討論類關(guān)系的時候, 常常會用UML類關(guān)系圖來示意. UML是一種通用建模語言, 全稱Unified Modeling Language, 是一種用來給軟件建模的可視化的規(guī)約語言. 因?yàn)樵跇I(yè)界影響力很大, 逐漸成為一種建模設(shè)計(jì)語言的標(biāo)準(zhǔn). GoF設(shè)計(jì)模式的關(guān)系圖也都是基于UML的, 所以我們有必要了解下UML的類關(guān)系表達(dá)方式.
通常, 類關(guān)系分成六種, 關(guān)系說明和UML表達(dá)方式如下:
可能單純這樣看比較抽象, 也難以記憶, 我們可以找個實(shí)際的例子來看看:
以上關(guān)系的強(qiáng)弱關(guān)系:
泛化 = 實(shí)現(xiàn) > 組合 > 聚合 > 關(guān)聯(lián) > 依賴
從我們軟件設(shè)計(jì)的角度, 肯定是傾向于越弱的關(guān)系越好的, 弱關(guān)系才可以松耦合. 所以也有我們常聽到的組合優(yōu)于繼承.
萬物唯變不變
唯一不變的是變化本身
斯賓塞.約翰遜 <<誰動了我的奶酪>>
運(yùn)動是絕對的, 靜止是相對的, 生活中的一切人, 事, 物和關(guān)系都在不斷的變化. 同樣, 軟件世界也會一直面臨著各種變化, 我們的程序怎么去以最小的代價去應(yīng)對這些變化 --- 這就是我們面向?qū)ο笤O(shè)計(jì)要解決的問題.