敏捷開發原則-LSP(替換原則)

LSP(Liskov Substitution Principle)程序員

  定義:子類型必須可以替換掉它們的基類型。spa

  若對每一個類型S的對象o1,都存在一個類型T的對象o2。使得在全部針對T編寫的程序P中,用o1替換o2後,程序P的功能不變,則說明S是T的子類型!code

 

一個違反該原則的例子對象

長方形:blog

public class Rectangle { private double _width; private double _height; public void SetWidth(double w) { _width = w; } public void SetHeight(double w) { _height = w; } public double GetWidth() { return _width; } public double GetHeight() { return _height; } }

正方形:繼承

public class Square extends Rectangle{ public void SetWidth(double w) { super.SetWidth(w); super.SetHeight(w); } public void SetHeight(double w) { super.SetWidth(w); super.SetHeight(w); } }

 

一般來講繼承關係就是is-a的關係,若是一個對象A is-a另外一個對象B,那麼能夠說這個對象A就是從另外一個B繼承而來。ip

很顯然一個正方形is-a長方形,因此知足這種繼承關係。ci

可是因爲正方形4邊相等,沒有所謂的長寬之分,因此它對setWidth和setHeight作了修改來規避長寬問題。it

這個時候當正方形的一個寬發生改變,長也會相應的改變,來實現正方形的4邊相等。io

public void g(Rectangle r) { r.SetWidth(5); r.SetHeight(4); Assert.AreEqual(r.GetWidth() * r.GetHeight(), 20); }

可是這個時候執行g(Rectangle r) 方法就會出現問題。

上述例子明顯的違反了LSP原則,也潛在的違背了OCP原則。

從孤立的角度看,一個模型沒法本身進行有意義地驗證。模型的正確性僅能經過它的使用者來表達。例如,孤立地看 Square 和 Rectangle,咱們發現它們是自洽的而且是有效的。但當咱們從一個對基類作出合理假設的程序員的角度來看待它們時,這個模型就被打破了。

  結論:

    OCP是OOD的核心,而LSP則是OCP的主要原則之一,正是子類的可替換性才使得使用基類類型的模塊在無需修改的狀況下就能夠拓展。

    術語is-a的範圍過於普遍,有上述例子致使該術語不能有效的定義子類。因此以爲子類的定義應該是「可替換性」。

相關文章
相關標籤/搜索