设计模式的设计原则(三)

依赖倒置原则

依赖倒置原则(Dependence Inversion Principle, DIP)的定义:
High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.
翻译过来,有三重含义:
高层模块不应该依赖底层模块,两者都应该依赖其抽象。
抽象不应该依赖细节。
细节应该依赖抽象。
更加精髓的定义就是"面向接口编程"——面向对象设计的精髓之一。

依赖倒置原则在Java语言中的表现就是:
模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。
接口或抽象类不依赖于实现类。
实现类依赖与接口或抽象类。

采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并发开发引起的风险,提高代码的可读性和可维护性。

依赖是可以传递的。只要做到抽象依赖,即使是多层的依赖传递也无所畏惧。
** 为了说明依赖倒置到底干了什么,我们以一个反例来说明,如果不使用依赖倒置,会发生什么事情 **
我有一辆奔驰车,奔驰车有个方法能启动它

package 依赖倒置原则反证;

public class Benz {

    public void run() {
        System.out.println("奔驰启动。。。");
        
    }

}

我还有一辆宝马车,宝马车有个方法能启动它

package 依赖倒置原则反证;

public class BMW {
    public void run() {
        System.out.println("宝马启动。。。");
    }

}

我现在想找个司机,司机有个dirve方法可以开车,可是这个司机有个怪毛病,他在开车之前必须告诉他要开什么车,否则他不开。

package 依赖倒置原则反证;

/**
 * 司机源代码,司机和奔驰车是紧耦合关系,目前司机只能开奔驰,哪怕我的宝马方法已经建好了,司机也不能开宝马
 * @author xuxiao
 *
 */
public class Driver {
    //司机和奔驰紧耦合,司机只能开奔驰
    public void dirve(Benz benz) {
        benz.run();
    }
}

有没有解决方案呢,肯定有啊,我们应该学过方法的重载了,只要参数不同,我们就可以写一个新的drive方法来让司机可以开两种车。

public void dirve(BMW bmw) {
        bmw.run();
    }
package 依赖倒置原则反证;

public class Client {
    public static void main(String[] args) {
        Driver zhangsan = new Driver();
        Benz benz = new Benz();
        zhangsan.dirve(benz);
        //现在司机想开宝马车了,但是drive方法和奔驰是紧耦合的关系,无法实现。
        //解决方案只有在driver类中重载drive方法,这样真的好吗?
    }

}

我们来设想一个场景,要是我家就是卖车的,有几百种型号,司机每次开之前都来问我,这车啥牌子的,不说我就不开!对应到程序里就是我要把drive方法重载几百次。
那依赖倒置怎么解决这个问题?
车子抽象为接口,所有车都实现这个接口

package 依赖倒置原则;

public interface ICar {
    public void run();
}
package 依赖倒置原则;

public class Benz implements ICar{

    public void run() {
        System.out.println("奔驰启动。。。");
        
    }

}
package 依赖倒置原则;

public class BMW implements ICar{
    public void run() {
        System.out.println("宝马启动。。。");
    }

}

司机也抽象为接口,是司机就会开车,不管车型号

package 依赖倒置原则;

public interface IDriver {
    public void drive(ICar car);
}
package 依赖倒置原则;

/**
 * 
 * @author xuxiao
 *
 */
public class Driver implements IDriver{
    @Override
    //司机只管开车,开的什么车?不知道!我开的的是抽象的车,什么都行
    public void drive(ICar car) {
        car.run();  
    }

}

再来看场景类

package 依赖倒置原则;

public class Client {
    public static void main(String[] args) {
        
        //zhangsan的声明类型是IDriver,zhangsan的实际类型是Driver
        IDriver zhangsan = new Driver();
        Benz benz = new Benz();
        BMW bmw = new BMW();
        zhangsan.drive(benz);
        zhangsan.drive(bmw);
        
    }

}

最佳实践:
每个类尽量都有接口或抽象类,或者两者都具备。接口负责定义public属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共构造部分的实现,实现类准确的实现业务逻辑,同时在适当的世界对父类进行细化。
变量的表面类型尽量是接口或者是抽象类。
任何类都不应该从具体类派生。
尽量不要覆写(Override)基类的方法。
结合里氏替换原则使用。

"面向接口编程"是依赖倒置原则的核心。

一个项目的终极目标,是投产上线和盈利。技术只是实现目的的工具。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容