設計模式中的里氏代換原則
Table of Contents
1 里氏代換原則
從開-閉原則中可以看出來面向對象的重要原則是創建抽象化,並從抽象化導出具體化。具 體化可以給出不同的版本,每一版本都給出不同的實現。里氏代換原則從另一個側面描述 抽象化和具體化,里氏代換原則表明:一個軟件如果使用的是一個基類的話,那么一定適 用於其子類,而且它根本不可能察覺出基類對象和子類對象的區別;必須指出,這個原則 反過來不一定成立,即一個軟件實體使用的是一個子類的話,那么它不一定適用於基類。
2 模式中的里氏代換原則
2.1 策略模代
策略模式講的是:如果有一組算法,那么就將每一個算法封裝起來,使它們可以互換。 封裝的概念不難理解,而使算法可以互換大,則需要將具體策略角色放到一個類型等級 結構中,使它們擁有共同的接口,這種互換性依賴的是里氏代換原則。從策略模式uml中 可以看出,客戶端依賴於基類類型,而真實類型是具體的策略類(子類),這是具體策略 角色可以即插即用的關鍵。
策略模式
2.2 合成模式
合成模式通過使用樹結構描述整體與部分的關系,從而可以將葉子元素和復合元素同等 看待,由於葉子元素和復合元素都是抽象角色的子類,因此兩者都可以替代抽象角色出 現的任何地方,顯然,里氏代換原則是合成模式能夠成立的基礎。
合成模式
2.3 代理模式
代理模式給某一對象提供一個代理對象(Proxy),並由代理對象控制原對象 (RealSubject)的引用,代理模式能夠成立的關鍵,在於代理對象和原對象都是抽象角色 (Subject)的子類,客戶端只知道抽象角色,而代理對象可以代替抽象角色出現在任何地 方,而將原對象隱藏在幕后。
代理模式
3 如何繼承
3.1 不要從具體類繼承
只要有可能,不要從具體類繼承,如圖,給出了一個繼承形成的等級結構例子,可以看 出,所有子類都是從接口或抽象類繼承,具體類沒有子類。換言之,在一個繼承關系形 成的等級結構里,樹葉節點均應是具體類,而樹枝節點均應是接口或抽象類。
不從具體類繼承
3.2 避免錯誤繼承
抽象化(包括接口和抽象類)通常代表一個抽象概念,它提供一個繼承的出發點,而具體類 則不同,具體類可以實例化,應當給出一個有商業邏輯實現的對象模板,不應當做為超類。 子類應當擴展超類的責任,而不是置換或撤消超類的責任。如果有兩個具體類有繼承關 系,通常子類需要將繼承自超類的責任取消或置換后才能使用,很可能這個子類根本就不 是那個超類的子類,這樣的設計可以優化。
將狗設計成貓的子類,如圖所示,貓有上樹的能力,狗沒有,為了繼承關系成立,只好將 貓上樹的能力取消掉,這個關系顯然是錯誤的。正確的繼承關系是引入一個抽象類,在這 里就是動物類,兩個具體類設計成抽象類的子類。
正確繼承
Date: 2014-07-19 17:08:07
HTML generated by org-mode 6.21b in emacs 23