《设计模式之禅》之依赖倒置原则
,Dependence Inversion Principle(DIP),核心就是面向接口编程,而不是面向实现编程。
高层模块不应该依赖低层模块,两者都应该依赖其抽象。 接口或抽象类不依赖于实现类 实现类依赖接口或抽象类
public class Driver {
//司机的主要职责就是驾驶汽车
public void drive(Benz benz){
benz.run();
}
}
书中的例子,司机 Dirver 类内部用了奔驰汽车 Benz 类,这就是具体的类支持相互依赖,耦合高,如果还有一个宝马汽车 BMW 类,由于 drive 定死了参数,导致无法使用 BMW 对象。
所以应该抽象一个 ICar 接口,让 Benz 和 BMW 实现它,drive 的参数用 ICar。这还不彻底,还是具体的类 Driver,所以还抽象一个 IDriver 接口,变成纯接口之间依赖。
public interface IDriver {
//是司机就应该会驾驶汽车
public void drive(ICar car);
}
还有个好处就是多人并行开发,先定义好接口,实现各干各的,彼此不影响进度。
public class Client {
public static void main(String[] args) {
private IDriver zhangsan = new Driver();
private ICar benz = new Benz();
zhangsan.drive(benz)
}
}
一开始真没看出来有什么作用,下面的代码和上面的代码能有什么区别?
Driver zhangsan = new Driver();
Benz benz = new Benz();
zhangsan.drive(benz);
说 Client 作为更高层的业务,作为高层模块不应该依赖低层模块,所以不应该直接用 Driver,Benz 这种具体的实现,而是要用抽象的 IDriver,ICar,zhangsan 都当作 IDriver 用,屏蔽了 Driver 细节的影响,这里大概明白了原因。
假设 zhangsan 这个 Driver 不仅可以 drive(ICar)
,还可以 fly(IPlane)
,现在 Client 这种高层业务显然只想用他作为 IDriver 的通用功能,即 drive,别的具体的实现能飞,还是能潜水,对于 Client 来说,不想知道,不想关注。如果写成 Driver zhangsan
,那么可能后来有个人接手代码了,说原来 zhangsan 可以飞呀,那干吗还要开车这么慢,直接开飞机了。如果业务后面有个判断说如果行驶距离超过50公里了就强制休息一下,如果用 Driver,然后有人用 fly,那可能就坠机了,但如果用 IDriver,接口里只有 drive,用的人也只能开车,要休息那就在路上停一会就行。
不知是不是这么理解的?
后来讲三种对象注入方法,构造函数、setter 方法、上面的接口方式,想到依赖注入框架 Dragger,在那看到过这些注入介绍,嫌弃这么注入不好,用注解做。
最佳实践: