標籤:
2. 裡氏替換原則:LSP(Liskov Substitution Principle)裡氏替換原則,定義為只要父類出現的地方子類就可以出現,而且用子類替換後,程式也不會出現問題,使用者根本不用關心是父類還是子類。這也是我們java繼承特性的一個表現。
下面用個實際項目中遇到的一個簡單的需求:現在有A類產品需要調用method1(),B類產品也需要調用method(),同樣C類產品也需要調用method(),但是我們需要直接讓D這個人去處理這個Method(),那麼我們可以這樣設計一個抽象類別AbstractB(或者介面)。
AbstractB類代碼如下:
1 public abstract class AbstractB {2 //實現邏輯3 public abstract void Method();4 }
下面A,B,C類分別繼承抽象類別AbstractB:
1 public class A extends AbstractB {2 3 @Override4 public void Method() {5 System.out.println("A實現Method....");6 }7 8 }
public class B extends AbstractB { @Override public void Method() { System.out.println("B實現Method...."); } }
public class C extends AbstractB { @Override public void Method() { System.out.println("C實現Method...."); } }
設計D類
1 @SuppressWarnings("unused") 2 public class D { 3 4 public AbstractB abstractObj; 5 6 public void setRealObj(AbstractB realObj){ 7 this.abstractObj = abstractObj; 8 } 9 10 public void invocateMethod(){11 //方法調用12 abstractObj.Method();13 }14 }
注意:在類中調用其他類對象的時候,必須要使用父類或者介面,如果沒有的話,則說明違背了LSP原則。
寫個測試類別:
1 public class test { 2 3 public static void main(String[] aa){ 4 D d = new D(); 5 d.setRealObj(new A()); 6 /*d.setRealObj(new B()); 7 d.setRealObj(new C());*/ 8 d.invocateMethod(); 9 }10 11 }
上面的setRealObj方法中,傳遞一個子類實體,這裡制定的是父類類型,這裡我們不用關心傳遞的是父類還是子類。相反如果參數類型為子類,傳遞的一個父類的類型,這時就不一定適用。就與裡氏替換原則違背,如果現在有個E產品也需要實現Method方法,只需再實現抽象類別AbstractB即可。
裡氏替換原則的目的就在於增強程式的健壯性,便於系統的相容性。及時增加子類也可以很好的滿足要求繼續執行。
3、依賴倒轉原則:DIP(Dependence Inversion Principle)
這個是開閉原則的基礎,具體內容:面向介面編程(OOD),依賴於抽象而不依賴於具體,用到具體類時,不與具體類互動,而與具體類的上層介面或者抽象類別互動。
這個其實與LSP挺相似的。都是盡量與上層互動。看段代碼說話。
比如說司機開汽車,車子有寶馬,有平治,有其他的型號的汽車。
定一個司機介面Driver
1 public interface IDriver {2 public void drive();//開車3 }
定義一個汽車介面Car
1 public interface ICar {2 public void run();//汽車奔跑3 }
定義寶馬,平治實現汽車介面
1 public class Benz implements ICar {2 3 @Override4 public void run() {5 System.out.println("平治跑起來....");6 }7 8 }
public class Bmw implements ICar { @Override public void run() { System.out.println("寶馬跑起來...."); }
}
實現司機介面:
public class Driver implements IDriver { public ICar car; //這裡用建構函式傳遞依賴對象 public Driver(ICar _car){ this.car = _car; } @Override public void drive() { this.car.run(); }}
實現依賴注入還有另外兩種方式。seter方法注入、介面聲明傳遞。
依賴倒置本質就是通過抽象類別或介面實現各個類或者模組彼此獨立化,實現模組間的松耦合。我們盡量遵循以下幾點:
第一:每個類盡量都有介面或者抽象類別或者兩者都有。
第二:變數的表面類型盡量是介面或者抽象類別。
第三:盡量不要具體類派生,盡量不要複寫基類的方法。
第四:結合裡氏替換原則使用。個人感覺兩者其實意義上有很大的相同。
通俗的講,倒置的概念我認為就是用抽象代替細節實在,這就是倒置。
持續更新中......
淺析JAVA設計模式(二)