主目錄:一個面向對象設計(OOD)的學習思路設計java
引入: 高層的決定不能由於某一個低層次模塊的變更而影響全局,致使整個系統的變更。編程
結構以下:學習
代碼以下:this
/** * 高層 */
class GaoCeng {
ZhongCeng mZhongCeng;
public GaoCeng(ZhongCeng mZhongCeng) {
this.mZhongCeng = mZhongCeng;
}
}
/** * 中層 */
class ZhongCeng{
DiCeng mDiCeng;
public ZhongCeng(DiCeng mDiCeng){
this.mDiCeng = mDiCeng;
}
}
/** * 底層 */
class DiCeng{
}```
3. 依賴倒置正面教材
> 結構以下:

> 代碼以下:
``` java
/** * 中層接口 */
interface ZhongCengInterface{
}
/** * 高層接口 */
interface GaoCengInterface{
}
/** * 高層 */
class GaoCeng {
GaoCengInterface mGaoCengInterface;
public GaoCeng(GaoCengInterface mGaoCengInterface) {
this.mGaoCengInterface = mGaoCengInterface;
}
}
/** * 中層 */
class ZhongCeng implements GaoCengInterface{
ZhongCengInterface mZhongCengInterface;
public ZhongCeng(ZhongCengInterface mZhongCengInterface){
this.mZhongCengInterface = mZhongCengInterface;
}
}
/** * 底層 */
class DiCeng implements ZhongCengInterface{
}
複製代碼
既然咱們理解了DIP,那麼DIP的好處不言而喻。spa
既然有好處,那麼就一定有壞處:代碼的增長,學習成本和代碼思考時間的增長。(不過相對於後期的好處,這點咱們仍是能理解的)設計
其實理解DIP的例子就是一個很好的對比例子。 如今來一個實際一點的例子:超重提價code
以傳統方式編程對象
/** * 稱重器傳統編程 */
class Scales{
private double readValue;//獲取到的物體的重量
private double highestValue;
private double inPrice;
private double outPrice;
public Scales(double highestValue, double inPrice, double outPrice) {
this.highestValue = highestValue;
this.inPrice = inPrice;
this.outPrice = outPrice;
}
/** * 當有物體放上去後稱重 */
public void startScales() {
//...readValue = ? (這裏獲取稱重器計算的重量)
showWeigh(readValue);
double price = 0;
double diff = readValue - highestValue;
if (diff > 0) {
outWeighWarn(diff);
price += highestValue * inPrice;
price += diff * outPrice;
} else {
price += readValue * inPrice;
}
showPrice(price);
}
/** * 顯示重量 */
private void showWeigh(double weigh) {
}
/** * 超重提醒 */
private void outWeighWarn(double outWeigh) {}
/** * 顯示價格 */
private void showPrice(double price) {
}
}
複製代碼
依賴倒置後接口
/** 稱重接口*/
interface Weigh {
double read();
}
/** 最大重量、範圍內價格、範圍外價格的設置*/
interface Value{
double highestValue();
double inPrice();
double outPrice();
}
/** 顯示器接口*/
interface Show {
void outWeighWarn(double diff);
void showWeigh(double weigh);
void showPrice(double price);
}
class Scales{
private Weigh mWeigh;
private Show mShow;
private Value mValue;
public Scales(Weigh mWeigh, Show mShow, Value mValue) {
this.mShow = mShow;
this.mWeigh = mWeigh;
this.mValue = mValue;
}
/** * 當有物體放上去後稱重 */
public void startScales() {
mShow.showWeigh(mWeigh.read());
double price = 0;
double diff = mWeigh.read() - mValue.highestValue();
if (diff > 0) {
mShow.outWeighWarn(diff);
price += mValue.highestValue() * mValue.inPrice();
price += diff * mValue.outPrice();
} else {
price += mWeigh.read() * mValue.inPrice();
}
mShow.showPrice(price);
}
}
複製代碼
咱們能夠看出依賴倒置後使代碼可複用,能夠是任意的稱重裝置,能夠是任意的顯示裝置,只要它們實現對應的接口便可。高層沒必要在乎底層具體是什麼東西。ip
每一個程序都會有違反這些規則的狀況,有時必須建立具體類的實例。此外,這些規則對於那些具體但卻穩定的類來講彷佛不太合理。若是一個具體類不太會改變,而且也不會建立其餘相似的派生類,那麼依賴於它並不會形成損害,好比說String類型。
然而,咱們編寫的大多數具體類都是不穩定的,咱們將它們隱藏在抽象接口後面,隔離它們的不穩定性。
因爲抽象將高層和細節彼此隔離,因此代碼也很是容易維護
[^foot1]: 敏捷軟件開發 第12章 依賴倒置原則(DIP)