物件導向設計原則之里氏代換原則
里氏代換原則由2008年圖靈獎得主、美國第一位電腦科學女博士Barbara Liskov教授和卡內基·梅隆大學Jeannette Wing教授於1994年提出。其嚴格表述如下:如果對每一個型別為S的物件o1,都有型別為T的物件o2,使得以T定義的所有程式P在所有的物件o1代換o2時,程式P的行為沒有變化,那麼型別S是型別T的子型別。這個定義比較拗口且難以理解,因此我們一般使用它的另一個通俗版定義:
里氏代換原則(Liskov Substitution Principle, LSP):所有引用基類(父類)的地方必須能透明地使用其子類的物件。 |
里氏代換原則告訴我們,在軟體中將一個基類物件替換成它的子類物件,程式將不會產生任何錯誤和異常,反過來則不成立,如果一個軟體實體使用的是一個子類物件的話,那麼它不一定能夠使用基類物件。例如:我喜歡動物,那我一定喜歡狗,因為狗是動物的子類;但是我喜歡狗,不能據此斷定我喜歡動物,因為我並不喜歡老鼠,雖然它也是動物。
例如有兩個類,一個類為BaseClass,另一個是SubClass類,並且SubClass類是BaseClass類的子類,那麼一個方法如果可以接受一個BaseClass型別的基類物件base的話,如:method1(base),那麼它必然可以接受一個BaseClass型別的子類物件sub,method1(sub)能夠正常執行。反過來的代換不成立,如一個方法method2接受BaseClass型別的子類物件sub為引數:method2(sub),那麼一般而言不可以有method2(base),除非是過載方法。
里氏代換原則是實現開閉原則的重要方式之一,由於使用基類物件的地方都可以使用子類物件,因此在程式中儘量使用基類型別來對物件進行定義,而在執行時再確定其子類型別,用子類物件來替換父類物件。
在使用里氏代換原則時需要注意如下幾個問題:
(1)子類的所有方法必須在父類中宣告,或子類必須實現父類中宣告的所有方法。根據里氏代換原則,為了保證系統的擴充套件性,在程式中通常使用父類來進行定義,如果一個方法只存在子類中,在父類中不提供相應的宣告,則無法在以父類定義的物件中使用該方法。
(2) 我們在運用里氏代換原則時,儘量把父類設計為抽象類或者介面,讓子類繼承父類或實現父介面,並實現在父類中宣告的方法,執行時,子類例項替換父類例項,我們可以很方便地擴充套件系統的功能,同時無須修改原有子類的程式碼,增加新的功能可以通過增加一個新的子類來實現。里氏代換原則是開閉原則的具體實現手段之一。
(3) Java語言中,在編譯階段,Java編譯器會檢查一個程式是否符合里氏代換原則,這是一個與實現無關的、純語法意義上的檢查,但Java編譯器的檢查是有侷限的。
在Sunny軟體公司開發的CRM系統中,客戶(Customer)可以分為VIP客戶(VIPCustomer)和普通客戶(CommonCustomer)兩類,系統需要提供一個傳送Email的功能,原始設計方案如圖1所示: 圖1原始結構圖 在對系統進行進一步分析後發現,無論是普通客戶還是VIP客戶,傳送郵件的過程都是相同的,也就是說兩個send()方法中的程式碼重複,而且在本系統中還將增加新型別的客戶。為了讓系統具有更好的擴充套件性,同時減少程式碼重複,使用里氏代換原則對其進行重構。 |
在本例項中,可以考慮增加一個新的抽象客戶類Customer,而將CommonCustomer和VIPCustomer類作為其子類,郵件傳送類EmailSender類針對抽象客戶類Customer程式設計,根據里氏代換原則,能夠接受基類物件的地方必然能夠接受子類物件,因此將EmailSender中的send()方法的引數型別改為Customer,如果需要增加新型別的客戶,只需將其作為Customer類的子類即可。重構後的結構如圖2所示:
圖2 重構後的結構圖
里氏代換原則是實現開閉原則的重要方式之一。在本例項中,在傳遞引數時使用基類物件,除此以外,在定義成員變數、定義區域性變數、確定方法返回型別時都可使用里氏代換原則。針對基類程式設計,在程式執行時再確定具體子類。
|
【作者:劉偉 http://blog.csdn.net/lovelion】
相關文章
- 物件導向設計的六大原則(SOLID原則)-——里氏替換原則物件Solid
- 物件導向設計原則物件
- 開閉原則——物件導向程式設計原則物件程式設計
- 面象物件設計6大原則之三:里氏替換原則物件
- 物件導向之六大設計原則物件
- 里氏替換原則
- The Principles of OOD 物件導向設計原則物件
- 2.物件導向設計原則物件
- 物件導向設計原則和模式物件模式
- 物件導向的基本設計原則物件
- 嘻哈說:設計模式之里氏替換原則設計模式
- 物件導向之 開閉原則物件
- 設計模式的七大原則(4) --里氏替換原則設計模式
- Java中物件導向的設計原則Java物件
- 物件導向的編碼設計原則物件
- 物件導向OO原則物件
- 前端設計模式(0)物件導向&&設計原則前端設計模式物件
- 物件導向設計原則&設計模式分類物件設計模式
- 翻譯 | The Principles of OOD 物件導向設計原則物件
- 物件導向設計的6大原則物件
- 設計原則之【裡式替換原則】
- SOLID:物件導向設計的前五項原則Solid物件
- 61條物件導向設計的經驗原則物件
- 七種常見的物件導向設計原則物件
- 實驗1:UML與物件導向程式設計原則物件程式設計
- S.O.I.L.D 之里氏替換原則
- 不止於物件導向的SOLID原則物件Solid
- 物件導向程式設計(OOP)的七大原則物件程式設計OOP
- 軟體開發六大原則(三)-里氏替換原則
- 設計原則之【介面隔離原則】
- Laravel深入學習10 – 里氏替換原則Laravel
- DesignPattern系列__04里氏替換原則
- 物件導向的7大原則與23種設計模式物件設計模式
- 物件導向的六大原則物件
- 設計原則之【單一職責原則】
- 設計原則之【開放封閉原則】
- 設計原則之【依賴反轉原則】
- 面象物件設計6大原則之四:介面隔離原則物件
- 面象物件設計6大原則之五:依賴倒置原則物件