《设计模式之禅》之依赖倒置原则,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,在那看到过这些注入介绍,嫌弃这么注入不好,用注解做。
最佳实践: