2022年1月10日 星期一

[Geroge]面向對象設計-里式替換原則LSP

--影片內容--

里式替換原則(Liskov substitution Principle)

定義: 子類型必須能夠替換它們的基類型, 一個實體如果使用是一個基類, 那麼把這個基類替換成繼承該基類的子類, 程序的行為不會發生任何變化, 實體察覺不出基類對象和子類對象的區別

低耦合

優點: 可以很容易的實現同一父類下各個子類的互換, 而客戶端可以毫不察覺

---------------------------------------------

感覺影片的理論部分少了點

下面補充一下他網的資源

----------------------------------------------

關於背景:

1 當初由Liskov 女士提出, 下面這段話

繼承必須確保父類所擁有的性質在子類中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。

2 里式替換原則- 講述繼承的原則, 也就是什麼時候應該要用繼承, 也可以視為對開閉原則的補充, 為實現抽象化步驟的規範


關於作用:

1 實現開閉原則重要方法之一

2 克服了重寫父類造成可複用性變差的缺點

3 為動作正確性的保證, 新的類擴展, 不會給已有的系統帶來錯誤, 降低程式碼出錯機會

4 加強程式碼的穩健性, 同時變更時可以做到優良的兼容性, 提高程式可維護, 擴展性, 降低需求變更帶來的風險


關於定義

1 子類可以實現父類抽象方法, 但是不可以覆蓋父類非抽象方法

2 子類可以增加自己特有方法

3 子類方法重載父類的方法時, 前置條件要比父類方法更寬鬆

4 子類實現父類方法時, 方法後置條件要比父類方法更嚴格或相等

-----

範例

我們有一個父類Gun類別, 另外有兩個子類HandGun, Rifle去繼承它, 並有一個Soldier依賴Gun去完成殺敵的行為



















我們現在要新增一個ToyGun去繼承Gun, 然而我們發現, 它這裡發生了嚴重的邏輯錯誤, 因為ToyGun是不能殺敵的, 所以它在Soldier執行射擊之後, 完成殺敵的行為, 明顯有邏輯的錯誤, 這就是因為它違反了里式替換原則, 子類並不能完全替換父類功能











這時候我們必須重新來設計, 我們需要新加一個Weapon類

讓所有可攻擊的武器去繼承



而玩具槍去繼承Gun類別, 沒有射擊功能





類別圖如下







小心得

符合里式替換原則的程式, 的確有其穩健性, 避免程式邏輯錯誤

參考: 

https://www.youtube.com/watch?v=DWkggQoxFeI&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=6

https://github.com/iw5420/geroge-design-pattern

沒有留言:

張貼留言

[leetcode] [KMP] KMP

ABCDABD... ABCDABF... 簡單的說, 傳統解兩字串匹配部分 可能會來個雙迴圈, 哀個比對, 當不匹配的時候, 會將下方列再後移1位 然後不匹配再後移 然而 如果像上放已經有4個屬於匹配的字串, 她就應該直接往後移四位來匹配, 而不是只移動1位 隱藏的思維是, 當...