個人理解 ,隨手寫下的筆記。不足之處,請諒解。
定義
問題的由來
類A直接依賴類B,假如要將類A改為依賴類C,則必須通過修改類A的代碼來達成。這種場景下,類A一般是高層模塊,負責復雜的業務邏輯;類B和類C是低層模塊,負責基本的原子操作;假如修改類A,會給程序帶來不必要的風險。
依賴倒置有三種方式來實現
- 通過構造函數傳遞依賴對象; 比如在構造函數中的需要傳遞的參數是抽象類或接口的方式實現。
- 通過setter方法傳遞依賴對象; 即在我們設置的setXXX方法中的參數為抽象類或接口,來實現傳遞依賴對象。
- 接口聲明實現依賴對象,也叫接口注入;即在函數聲明中參數為抽象類或接口,來實現傳遞依賴對象,從而達到直接使用依賴對象的目的。
Java例子
1 很多地方引用的個人覺得也非常有代表性的一個例子:公司是福特和本田公司的金牌合作伙伴,現要求開發一套自動駕駛系統,只要汽車上安裝該系統就可以實現無人駕駛,該系統可以在福特和本田車上使用,只要這兩個品牌的汽車使用該系統就能實現自動駕駛。
/**
* 汽車接口
*/
public interface ICar {
void run();
void stop();
}
/**
* 自動駕駛系統
*/
public class AutoCarSystem {
//通過接口編程不和具體實現累有關系,只要每個車符合駕駛系統定義的功能就行了
private ICar car = null;
public AutoCarSystem(ICar car) {
this.car = car;
}
public void setCar(ICar car) {
this.car = car;
}
public void carRun() {
car.run();
}
public void carStop() {
car.stop();
}
}
/**
* Fute汽車實現駕駛系統的操作
*/
public class FuteCar implements ICar {
@Override
public void run() {
System.out.println("FuteCar run");
}
@Override
public void stop() {
System.out.println("FuteCar stop");
}
}
/**
* Benz汽車實現駕駛系統的操作
*/
public class BenzCar implements ICar {
@Override
public void run() {
System.out.println("BenzCar run");
}
@Override
public void stop() {
System.out.println("BenzCar stop");
}
}
調用Demo
public class TestDemo {
public static void main(String[] args) {
FuteCar futeCar = new FuteCar();
BenzCar benzCar = new BenzCar();
//實例化一個自動車載系統,安裝了不同的車上
//安裝了futeCar
AutoCarSystem autoCarSystem = new AutoCarSystem(futeCar);
autoCarSystem.carRun();
autoCarSystem.carStop();
//安裝benzCar
autoCarSystem.setCar(benzCar);
autoCarSystem.carRun();
autoCarSystem.carStop();
//如果想給奧迪也這個自動駕駛系統也想用到奧迪車上,就通過ICar實現一個奧迪車的類,然后直接按上自動駕駛系統就好了,就不需要改自動駕駛系統就能操作奧迪車了??梢詣邮衷囋?,體會體會。
}
}
控制端輸出結果
FuteCar run
FuteCar stop
BenzCar run
BenzCar stop
2.再來個例子,人看書,一個人可以看很多書
/**
* 書的內容
*/
public interface IBook {
//書的標題
String title();
//書的內容
String content();
}
/**
* 人讀書
* 讀什么書還不知道,只知道在讀書的標題和內容
*/
public class PeopleReadBook {
private IBook book = null;
public PeopleReadBook(IBook book) {
this.book = book;
}
public void setBook(IBook book) {
this.book = book;
}
public void readTitle() {
System.out.println("書名:" + book.title());
}
public void readContent() {
System.out.println("內容:" + book.content());
}
}
/**
* Java書實現了書的內容
*/
public class JavaBook implements IBook {
@Override
public String title() {
return "Java 入門到精通";
}
@Override
public String content() {
return "學習Java,精通到放棄";
}
}
/**
* C書實現了書的內容
*/
public class CBook implements IBook {
@Override
public String title() {
return "C 入門到精通";
}
@Override
public String content() {
return "學習C,精通到放棄";
}
}
調用Demo
public class TestDemo {
public static void main(String[] args) {
JavaBook javaBook = new JavaBook();
CBook cBook = new CBook();
PeopleReadBook peopleReadBook = new PeopleReadBook(javaBook);
peopleReadBook.readTitle();
peopleReadBook.readContent();
peopleReadBook.setBook(cBook);
peopleReadBook.readTitle();
peopleReadBook.readContent();
}
}
控制端輸出結果
書名:Java 入門到精通
內容:學習Java,精通到放棄
書名:C 入門到精通
內容:學習C,精通到放棄
參考
JAVA設計原則之依賴倒置原則
設計模式六大原則(3):依賴倒置原則
設計原則(四)依賴倒置原則(DIP)
設計模式6大原則:依賴倒置原則