依賴倒置原則定義,及倒置的兩種理解
阿新 • • 發佈:2019-02-12
依賴倒置原則定義
如下(可先不管)
- 高層模組不應該依賴低層模組,兩者都應該依賴抽象
- 抽象不應該依賴細節
- 細節應該依賴抽象
情景描述
當前有一家飲料店,裡面賣著很多飲料
設計如下
問題描述
- 這裡箭頭符號表示BeverageStore依賴Juice,及高層依賴於低層
- 在BeverageStore中,對應的是具體的飲料實現,具體程式碼如下
package headfirst.hd.dep;
public class BeverageStore {
//賣果汁
public Juice saleBeverage() {
//果汁的具體實現
Juice juice = new Juice();
return juice;
}
}
修改設計,為飲料提供統一介面
備註:這是網上很多教程講的例子,根據我自己的理解,這不是依賴倒置的體現,後來我會給出原因
核心程式碼變為一下程式碼,依賴變為不僅依賴低層元件的實現,而且還依賴低層元件的抽象,比之前還更糟糕
package headfirst.hd.dep;
public class BeverageStore {
//賣果汁
public Beverage saleBeverage() {
//果汁的具體實現
Beverage beverage = new Juice();
return beverage;
}
}
對這個程式碼再優化一下
package headfirst.hd.dep;
//這是網上最常見方式
public class BeverageStore {
//賣果汁
public Beverage saleBeverage(Beverage beverage) {
//做一些其他操作
return beverage;
}
}
客戶端Client
package headfirst.hd.dep;
public class Client {
public static void main(String[] args) {
BeverageStore store = new BeverageStore();
store.saleBeverage(new Juice());
}
}
對應設計變化為
- 高層依賴低層還是曾在,並且由更高層依賴了低層模組
- 我個人覺得這應該叫依賴轉移
引入工廠方法模式改進以上例子
工廠模式設計圖
核心程式碼
BeverageStore
package headfirst.hd.dep;
//工廠方法模式
public abstract class BeverageStore {
//賣果汁
public Beverage saleBeverage() {
//直接使用自身定義的抽象方法
Beverage beverage = createBeverage();
//做一些其他操作
return beverage;
}
/**
* 抽象類BeverageStore抽象方法定義,Beverage createBeverage()
* 表明createBeverage與BeverageStore為一體,關係為一根橫線,
* 兩者沒有實質依賴關係,因為在BeverageStore中,直接使用自身
* 定義方法createBeverage,在類BeverageStore的其他方法中,
* 直接使用該型別,具體實現具體類,延遲到子類
*/
abstract Beverage createBeverage();
}
BeverageStoreFactory
package headfirst.hd.dep;
//工廠方法模式
public class BeverageStoreFactory extends BeverageStore{
@Override
Beverage createBeverage() {
//可傳入引數,得到更多例項,
//或者BeverageStoreFactory2,多個工廠方法,都可以
return new Juice();
}
}
測試Client
package headfirst.hd.dep;
public class Client {
//優秀啦,一點都沒有低層模組程式碼
public static void main(String[] args) {
BeverageStore store = new BeverageStoreFactory();
store.saleBeverage();
}
}
理解加入模式前後的不同
加入前
加入後
主要區別體現在兩點
- store與product關係
加入工廠前,實際上還是具有依賴關係,實質上將依賴關係往更高層轉移
package headfirst.hd.dep;
//這是網上最常見方式
public class BeverageStore {
//賣果汁
public Beverage saleBeverage(Beverage beverage) {
//做一些其他操作
return beverage;
}
}
加入工廠後
//工廠方法模式
public abstract class BeverageStore {
//賣果汁
public Beverage saleBeverage() {
//直接使用自身定義的抽象方法
Beverage beverage = createBeverage();
//做一些其他操作
return beverage;
}
/**
* 抽象類BeverageStore抽象方法定義,Beverage createBeverage()
* 表明createBeverage與BeverageStore為一體,關係為一根橫線,
* 兩者沒有實質依賴關係,因為在BeverageStore中,直接使用自身
* 定義方法createBeverage,在類BeverageStore的其他方法中,
* 直接使用該型別,具體實現具體類,延遲到子類
*/
abstract Beverage createBeverage();
}
所有加入前還是具有依賴關係,所以是箭頭,加入工廠模式之後,為介面定義,為一體,所以屬於直線
2. storefactory取代了Client位置
加入前層級關係
加入後層級關係
倒置的兩種理解
第一種,從設計上理解
如果所示,正常都是高層呼叫低層,簡單推理一下
- product1(具體的實現)依賴於product(抽象)
- 由於引入工廠模式後,store與product為同一關係(同時存在)
- 推理出,product1(具體的實現)依賴於store
因此,形成了依賴倒置的現象
第二種,從思想上理解
沒有引入工廠方法模式之前,我們需要一杯果汁(Juice),我們的思路時候這樣的
先有一個飲料店(BeverageStore),然後才會有果汁(Juice),簡單的說就是先有飲料店,最後決定賣什麼飲料
引入工廠方法模式之前,我們需要一杯果汁(Juice),我們的思路時候這樣的
先定義飲料介面,後實現具體的飲料店,這些我們可以理解為,我們先選擇什麼要的飲料,最後決定開什麼樣的飲料店
因此,形成了依賴倒置的現象