您的位置:首页 > 其它

设计模式笔记(三)设计六大原则之三--依赖倒置原则

2017-11-07 23:35 483 查看
Dependence Inversion Principle, DIP

定义

1.高层模块不应该依赖底层模块,两者都应该依赖其抽象

2.抽象不应该依赖细节

3.细节应该依赖抽象

即:

1.模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;

2.接口或抽象类不依赖于实现类

3.实现类依赖接口或抽象类

优点

1.减少类间的耦合性,提高系统稳定性

举个栗子:

/*
* 司机
*/
public class Driver {
//司机的主要职责就是驾驶汽车
public void drive(Benz benz) {
benz.run();
}
}


/*
* 奔驰汽车
*/
public class Benz {
//汽车肯定会跑
public void run() {
System.out.println("奔驰汽车开始运行...");
}
}


/*
* 司机开车场景模拟
*/
public class Client {
public static void main(String[] args) {
Driver zhangSan = new Driver();
Benz benz = new Benz();
//张三开奔驰车
zhangSan.drive(benz);
}
}


现在司机不仅要开奔驰车,还要开宝马车:

/*
* 宝马车
*/
public class BMW {
//宝马车开动
public void run() {
System.out.println("宝马汽车开始运行...");
}
}


但是我们现在发现,司机并不能开宝马车。这显然不合理,原因就是司机类和奔驰类是紧耦合的关系,这样一旦有新的车,比如宝马车来了,司机类就需要改动它的类代码,维护性大大降低,不稳定。

2.降低并行开发引起的风险,提高代码的可读性和可维护性。

现在开发的时候人员都是协作开发,可能每个人负责一个模块,也可能每个人负责一个类的编写或方法的编写。假如现在司机类由A来编写,奔驰车类由B来编写,很显然,在B编写完之前,A是不能开发成功的,为什么呢?编译器就不通过了,只能B开发完奔驰车类再由A来开发司机类,这样显然不利于项目进度,所以要解决模块之间的依赖关系。

按照依赖倒置原则,我们所有的高层模块都应该依赖于接口或抽象类。

/*
* 司机接口
*/
public interface IDriver {
//司机会驾驶汽车
public void drive(ICar car);
}


/*
* 司机
*/
public class Driver implements IDriver{
//司机的主要职责就是驾驶汽车
//  public void drive(Benz benz) {
//      benz.run();
//  }

@Override
public void drive(ICar car) {
car.run();
}
}


/*
* 汽车接口
*/
public interface ICar {
//汽车都能跑
public void run();
}


/*
* 奔驰汽车
*/
public class Benz implements ICar{
//汽车肯定会跑
public void run() {
System.out.println("奔驰汽车开始运行...");
}
}


/*
* 宝马车
*/
public class BMW implements ICar {
//宝马车开动
public void run() {
System.out.println("宝马汽车开始运行...");
}
}


/*
* 司机开车场景模拟
*/
public class Client {
public static void main(String[] args) {
Driver zhangSan = new Driver();
Benz benz = new Benz();
//张三开奔驰车
zhangSan.drive(benz);

//张三开宝马车
zhangSan.drive(new BMW());
}
}


这时我们要让司机开宝马车只需要实现汽车接口即可,司机类不需要改动任何代码,即接口或抽象类(IDriver)并不依赖于汽车时哪一种的(细节)。

依赖的三种写法

这里的原理是依赖是可以传递的,只要做到抽象依赖,那么多层的传递也是正确的。

构造函数注入

/*
* 司机接口
*/
public interface IDriver {
//司机会驾驶汽车
public void drive(ICar car);
}

public class Driver implements IDriver{
private ICar car;

//构造函数注入
public Driver(ICar _car) {
this.car = _car;
}

//司机的主要职责就是驾驶汽车
public void drive() {
this.car.run();
}
}


setter依赖注入

/*
* 司机接口
*/
public interface IDriver {
//车辆型号
public void setCar(ICar car);
//司机会驾驶汽车
public void drive(ICar car);
}

public class Driver implements IDriver{

private ICar car;

//构造函数注入
public void setCar(ICar _car) {
this.car = _car;
}

//司机的主要职责就是驾驶汽车
public void drive() {
this.car.run();
}
}


接口声明依赖对象

/*
* 司机接口
*/
public interface IDriver {
//车辆型号
public void setCar(ICar car);
//司机会驾驶汽车
public void drive(ICar car);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: