目录
查看其它设计模式笔记,点这里→设计模式笔记汇总
依赖倒置原则(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.
- 高层模块不应该依赖低层模块,两者都因该依赖抽象
- 抽象不应该依赖细节
- 细节应该依赖抽象
- 核心:
- 面向接口编程
- 实践方针:
- 变量不要持有具体类的引用(用工厂替代new)
- 类不要派生自具体类(应派生自抽象——接口或抽象类)
- 不要覆盖基类中已实现的方法(破坏基类的抽象性,基类中已实现的方法,应由所有子类共享)
- 我们不可能完全遵守上边这些方针,但其实这只是一种思维方式的形成与锻炼,让我们在设计时进行充分考虑。一个不怎么会改变的类,那么直接在代码中实例化是没有问题的。比如我们用了无数次的String。
- 作用:
- 减少类之间的耦合,提高系统稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。
- 示例:
- 张三是你的司机,负责开你的宝马。(这时候就有了Driver对象,内部有一个驾驶BMW对象的方法)。
- 但有一天你又买了辆奔驰,这下完蛋了,张三没有开奔驰的方法。
- 显然你不能再招一个专门开奔驰的司机,或者说去修改张三的基因,让他会开奔驰。
- 正确的做法是抽象出汽车对象,让宝马和奔驰实现汽车抽象。然后让Driver依赖汽车抽象。
- 这样只要在出差前,注入相应的汽车,张三就可以开动了。即使以后你买了兰博基尼也不用去动张三。
- 注入依赖的三种方法:(Car是汽车的抽象)
- 构造函数注入
public class Driver { private Car car; public Driver(Car car){ this.car = car; } public void drive() { this.car.run(); } }
- Setter方法注入
public class Driver { private Car car; public void setCar(Car car) { this.car = car; } public void drive() { this.car.run(); } }
- 接口声明注入
public class Driver { public void drive(Car car) { car.run(); } }
- 参考资料: