何為依賴導致原則?
Robert C. Martin在他的著作《敏捷軟件開發:原則、模式與實踐》中有這樣的兩句描述
1.High-level modules should not depend onlow-level modules. Both should depend on abstractions.(高層模塊不應該依賴於低層模塊,二者都應該依賴於抽象)
2.Abstractions should not depend upondetails. Details should depend upon abstractions.(抽象不應該依賴於具體實現細節,而具體實現細節應該依賴於抽象)
即,模塊類之間的依賴是基於抽象類的,實現類之間不能有直接的依賴關系,其依賴關系是通過接口或者抽象類產生的。
其核心思想是:要面向接口編程,不要面向實現編程。
基本概念
抽象與細節
在Java中,抽象就是指接口或者抽象類,兩者都是不能直接被實例化的;細節就是實現類,實現接口或者繼承抽象類而產生的就是細節,以關鍵字new產生對象。
高層與低層
通俗來講高層模塊就是調用端,低層模塊就是具體實現類。
具體實現
先看下不符合依賴導致原則會產生什么后果。
比如一個司機開奔馳車:
public class Driver{
public void drive(Benz benz){
benz.run();
}
}
public class Benz{
public void run(){
System.out.println("奔馳開始運行...")
}
}
public class Test{
public static void main(Sting[] args){
Driver zhangsan = new Driver();
Benz benz = new Benz();
zhangsan.drive(benz);
}
}
這樣zhangsan 就可以開奔馳了,但是如果zhangsan明天要開寶馬的車呢?
public class BMW{
public void run(){
System.out.println("寶馬車開始運行....");
}
}
他不能開,因為張三沒有開寶馬車的方法,除非要改driver類的方法。張三作為一個司機,居然沒法開別的品牌的車,這不符合常理。
下面引入了依賴倒置原則
創建司機接口
public interface IDriver{
public void drive(ICar car);
}
司機類實現司機接口
public class Driver implements IDriver{
public void drive(ICar car){
car.run();
}
}
定義汽車接口,具體車類實現接口
public interface ICar{
public void run();
}
public class Benz implements ICar{
public void run(){
System.out.println("奔馳騎車開始運行....");
}
}
public class BMW implements ICar{
public void run(){
System.out.println("寶馬騎車開始運行....");
}
}
測試
這里是高層業務邏輯,它對底層模塊的依賴(關聯)都建立在抽象上。
public class Client{
public static void main(String[] args){
IDriver zhangsan = new Driver();
ICar benz = new Benz();
ICar bmw = new BMW();
zhangsan.drive(benz);
zhangSan.drive(bmw);
}
}
這樣就實現了司機可以開任何品牌的汽車,添加新的品牌不需要修改司機類。
依賴倒置是指導代碼解耦的一個原則,通過增加一個抽象層來解耦低層和高層。
參考鏈接