基本介紹
依賴倒轉原則(Dependence Inversion Principle)是指:
1)高層模塊不應該依賴低層模塊,二者都應該依賴其抽象
2)抽象不應該依賴細節,細節應該依賴抽象
3)依賴倒轉(倒置)的中心思想是面向接口編程
4)依賴倒轉原則是基於這樣的設計理念:相對於細節的多變性,抽象的東西要穩定的多。以抽象爲基礎搭建的架構比以細節爲基礎的架構要穩定的多。在 java 中,抽象指的是接口或抽象類,細節就是具體的實現類
5)使用接口或抽象類的目的是制定好規範,而不涉及任何具體的操作,把展現細節的任務交給他們的實現類去完成
應用實例
1)實現方案 1 + 分析說明
public class DependecyInversion {
public static void main(String[] args) {
Person person = new Person();
person.receive(new Email());
}
}
class Email {
public String getInfo() {
return "電子郵件信息: hello,world";
}
}
//完成 Person 接收消息的功能
//方式 1 分析
//1. 簡單,比較容易想到
//2. 如果我們獲取的對象是 微信,短信等等,則新增類,同時 Perons 也要增加相應的接收方法
//3. 解決思路:引入一個抽象的接口 IReceiver, 表示接收者, 這樣 Person 類與接口 IReceiver 發生依賴
// 因爲 Email, WeiXin 等等屬於接收的範圍,他們各自實現 IReceiver 接口就 ok, 這樣我們就符號依賴倒轉原則
class Person {
public void receive(Email email ) {
System.out.println(email.getInfo());
}
}
2)實現方案 2(依賴倒轉) + 分析說明
public class DependecyInversion {
public static void main(String[] args) {
//客戶端無需改變
Person person = new Person();
person.receive(new Email());
person.receive(new WeiXin());
}
}
//定義接口
interface IReceiver {
public String getInfo();
}
class Email implements IReceiver {
public String getInfo() {
return "電子郵件信息: hello,world";
}
}
//增加微信
class WeiXin implements IReceiver {
public String getInfo() {
return "微信信息: hello,ok";
}
}
//方式 2
class Person {
//這裏我們是對接口的依賴
public void receive(IReceiver receiver ) {
System.out.println(receiver.getInfo());
}
}
依賴關係傳遞的三種方式和應用案例
1)接口傳遞
2)構造方法傳遞應用案例代碼
3)setter 方式傳遞
4)代碼演示
public class DependencyPass {
public static void main(String[] args) {
// TODO Auto-generated method stub ChangHong changHong = new ChangHong();
// OpenAndClose openAndClose = new OpenAndClose();
// openAndClose.open(changHong);
//通過構造器進行依賴傳遞
// OpenAndClose openAndClose = new OpenAndClose(changHong);
// openAndClose.open();
//通過 setter 方法進行依賴傳遞
OpenAndClose openAndClose = new OpenAndClose();
openAndClose.setTv(changHong);
openAndClose.open();
}
}
// 方式 1: 通過接口傳遞實現依賴
// 開關的接口
// interface IOpenAndClose {
// public void open(ITV tv); //抽象方法,接收接口
// }
//
// interface ITV { //ITV 接口
// public void play();
// }
//
// class ChangHong implements ITV {
//
// @Override
// public void play() {
// // TODO Auto-generated method stub
// System.out.println("長虹電視機,打開");
// }
//
// }
//// 實現接口
// class OpenAndClose implements IOpenAndClose{
// public void open(ITV tv){
// tv.play();
// }
// }
// 方式 2: 通過構造方法依賴傳遞
// interface IOpenAndClose {
// public void open(); //抽象方法
// }
// interface ITV { //ITV 接口
// public void play();
// }
// class OpenAndClose implements IOpenAndClose{
// public ITV tv; //成員
// public OpenAndClose(ITV tv){ //構造器
// this.tv = tv;
// }
// public void open(){
// this.tv.play();
// }
// }
// 方式 3 , 通過 setter 方法傳遞
interface IOpenAndClose {
public void open(); // 抽象方法
public void setTv(ITV tv);
}
interface ITV { // ITV 接口
public void play();
}
class OpenAndClose implements IOpenAndClose {
private ITV tv;
public void setTv(ITV tv) {
this.tv = tv;
}
public void open() {
this.tv.play();
}
}
class ChangHong implements ITV {
@Override
public void play() {
// TODO Auto-generated method stub
System.out.println("長虹電視機,打開");
}
}
依賴倒轉原則的注意事項和細節
1)低層模塊儘量都要有抽象類或接口,或者兩者都有,程序穩定性更好.
2)變量的聲明類型儘量是抽象類或接口, 這樣我們的變量引用和實際對象間,就存在一個緩衝層,利於程序擴展和優化
3)繼承時遵循里氏替換原則