iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
自我挑戰組

初階面試常見題目彙整系列 第 9

初階面試常見題目回答-SOLID(LSP)-鐵人賽第九日

  • 分享至 

  • xImage
  •  

里氏替換原則(Liskov Substitution Principle,LSP)是一個關於物件導向程式設計中子類別與父類別關係的原則。

聽起來非常的特別,而這一個原則,
也往往容易被違反的,
但就如同筆者一開始所說,
SOLID很重要,
但重點是違反是不是有他的必要性。

那麼LSP到底是什麼呢?

如果一個程式使用了一個父類別的物件,那麼用子類別的物件替換父類別的物件時,程式的行為功能不應該改變。也就是說,子類別應該完全遵循父類別的行為規範,不應該出現任何違反父類別期望的情況。
里氏替換原則可以用以下的數學公式來表示:
如果 S 是 T 的子型態,那麼對於任何型態為 T 的物件 x 和任何型態為 S 的物件 y,如果在所有針對 T 編寫的程式 P 中,用 y 替換 x 後,程式 P 的行為功能不變,那麼 S 就是 T 的子型態。

我相信有很多人都看不懂這個公式,
筆者也不怎麼喜歡寫這些公式,
那麼翻譯成文字會是三種條件。

子型態的先決條件(Preconditions)不應該被加強。
子型態的後置條件(Postconditions)不應該被削弱。
父型態的不變條件(Invariants)必須被子型態所保留。

按順序來解,何謂先決條件(Preconditions)呢?
先決條件是指在執行某個方法或動作之前,必須保證的狀態或條件。

可以想成如果要執行一件事情,
一定要某個狀態才能執行,
常見的例如需要能量才有辦法移動。

就以筆者所撰寫的程式來作為例子


public abstract class VehicleModel
{
	//執行此程式,先決條件 Gasoline > 0
	public abstract void Move();

	//執行此程式,傳出值一定大於等於0
	public int MovingDistance(int destination, int location)
	{
		return destination - location;
	}
}

裡面有Move與MovingDistance,
其中Move就有先決條件,
需要能源才能移動。

假如筆者製作一個汽車class有去繼承並實現Move這個function,
但如果筆者讓Gasoline <= 0的狀況下執行Move,
甚至根本沒去設定Gasoline這個屬性
這就是先決條件加強。

至於程式中如何設定先決條件呢?
其實並沒有規定說一定要怎麼樣才叫先決條件,
只要能有辦法讓其他工程師知道,
要執行這個function前需要什麼條件,
就可以說是先決條件。

常見的如同註解、寫在function外、把此funcion包在規則function裡、防呆的錯誤訊息等等,
甚至於消極到如果你不照這個條件就會直接出現Error,
這些都能算是先決條件。

何謂後置條件(Postconditions)呢?
簡單來說就是符合某些條件的前提下,
可以保證輸出一定符合這個條件,
要注意的是符合某些條件的前提中的某些,
指的也有可能沒有條件。

也有人說Postconditions就是指對輸出的約束,
告訴使用者:「這是我承諾為你做的」

像是MovingDistance,
如果它的作用是一個移動距離的function,原先只會計算移動多遠,所以傳出沒有正負號,
如果繼承的子類別帶入了方向性而導致傳出有正負號,
那麼這個後置條件(Postconditions)會是增強。

那這種條件下並不會違反,
因為這個function,
承諾了計算移動距離,
所以這不會是違反。

但如果某個function的作用是里程表,細節為計算總共移動多少距離,所以沒有方向性,只會永遠增加。
如果繼承的子類別帶入了方向性而導致傳出有正負號,會出現增加減少,
那麼這個後置條件(Postconditions)會是增強還削弱?

答案會是削弱,就算是算式一樣,
但承諾的不同,會帶來不同的限制。

不變條件(Invariants)
簡單來說某個條件不能增強或削弱,
例如Move的時候一定有能源,

比較正式的說法就是
Invariants指的是在一個系統或一段程式中保持不變的性質或表達式。
不變條件可以用來描述系統或程式的狀態、限制、規則、對稱性等方面,幫助理解、設計、測試和驗證系統或程式的功能和正確性。

常見的有迴圈不變式(Loop Invariant)

---歷史
LSP由美國計算機科學家芭芭拉·利斯科夫(Barbara Liskov)在1987年提出,並在1994年與周以真(Jeannette Wing)共同發表了一篇論文來詳細說明這個原則。
https://zh.wikipedia.org/zh-tw/%E9%87%8C%E6%B0%8F%E6%9B%BF%E6%8D%A2%E5%8E%9F%E5%88%99
里氏替換原則.維基百科


上一篇
初階面試常見題目回答-SOLID(OCP)-鐵人賽第八日
下一篇
初階面試常見題目回答-SOLID(ISP)-鐵人賽第十日
系列文
初階面試常見題目彙整30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言