1. 程式人生 > >面向物件的五大設計原則之里氏替換原則

面向物件的五大設計原則之里氏替換原則

里氏替換原則(liskov substitution principle,簡稱LSP)的核心只有一句話,subtypes must be substitutable for their base types(子類必須能夠替換成它們的基類),關於它的定義和主要的思想如下:

由於面向物件程式設計技術中的繼承再具體的程式設計過程中過於簡單,在許多系統的設計和程式設計實現中,我們並沒有認真的、理性的思考應用系統中各個類之間的繼承關係是否合適,派生類是否能正確的對其它基類中的某些方法進行重寫等問題,因此,經常出現濫用繼承或者錯誤的進行了繼承等現象,給系統後期的維護,帶來了不少麻煩,這就需要我們設計一個原則來遵循,所以,里氏替換原則,應運而生。

里氏替換原則指出,子型別必須能夠替換掉它們的父型別,並出現在父類能夠出現的任何地方,這個原則指導我們如何正確的進行繼承和派生,並且合理的重用程式碼,這個原則認為,一個軟體實體,如果使用一個基類的話,那麼一定適用於其子類,而且根本察覺不出來基類物件和子類物件之間的區別,感覺跟多型有點類似。

因為繼承和派生是面向物件(OOP)的一個主要特徵,而里氏替換原則則能夠解決減少程式碼的重複程式設計實現、實現系統的程式碼複用、正確合理的使用和設計繼承,來看下具體的方式。

首先,父類方法都要在子類中實現或者重寫,並且派生類只是實現其抽象類中宣告的方法,而不應當給出多餘的方法定義或者實現,其次,在客戶端程式中,只應該使用父類物件,而不能直接使用子類物件,這樣可以實現執行期的繫結(動態繫結),最後呢,如果A、B兩個類違反了里氏替換原則,通常的做法就是建立一個新的抽象類C,作為兩個類的超類,將A和B的共同行為,移植到C中,從而解決A和B行為不完全一致的問題。

其實,PHP對於里氏替換原則的支援並不好,它本身缺乏向上轉型啊什麼的概念,我們來看一個關於快取實現抽象類的程式碼感受下,抽象程式碼應該咋寫,沒有具體的實現類啊:

/*設定快取實現抽象類*/
abstract class cache
{
    /*設定快取變數,$k鍵值,$v快取值,$time快取過期時間*/
    public abstract function set($k,$v,$time=60);
    /*獲取已經快取的一個變數*/
    public abstract function get($k);
    /*刪除一個已經快取的變數*/
    public abstract function del($k);
    /*刪除全部快取變數*/
    public abstract function del_all();
    /*檢測是否存在相對應的快取*/
    public abstract function has($k);
}

我們如果要用作什麼memcache等各種機制下的快取,只需要繼承這個抽象類並且實現抽象類中的方法就好了。

我們要注意的是,里氏替換原則中替換的不僅僅是功能,還包括語意。

好啦,本次記錄就到這裡了。

如果感覺不錯的話,請多多點贊支援哦。