依赖倒置原则(DIP)
高层模块不应该依赖于底层模块,二者都应该依赖于抽象;细节应依赖于抽象.
- 传统习惯中,高层模块依赖于底层模块,策略依赖于细节的结构.
- 这是要定义子程序层次结构,该层次结构描述了高层模块如何调用底层模块.
- 但是,这也就意味着,底层模块的更改会直接影响到高层模块.而APP的区别就是体现在这些高层模块中的.
- 包含高层业务规则的模块应该优先并独立于包含细节的模块.
- 通过子程序库来重用底层模块.
- 我们更希望能够重用高层的策略设置模块.这也是Framework设计的核心.所以必须将高层独立于底层模块.
- 倒置的接口所有权.底层实现了高层中声明并被高层调用的接口.这样高层可以在任何实现了该接口的环境中重用.
- 有点短视的启发规则:程序中所有的依赖关系应该终止于抽象类或者接口.
- 变量不应该持有一个具体类.
- 类不应该从具体派生.
- 方法不应该复写它的基类中已经实现了得方法.
- 但是,创建稳定的类的实例是无害的.
- 依赖于稳定的类也是无害的.
- 所以,由客户类来声明它们需要的接口.仅当客户需要时才会对接口进行改变.从而,改变实现接口的类是不会影响到客户的.
- DIP可以应用于任何存在一个类向另一个类发送消息的场景.
- 可以使用模板方法来实现静态多态性.
- 不能在运行时更改模板使用的类型.
- 对新的Thermomerter/Heater实现类,都会导致重新编译和部署.
- 但是它避免了动态多态性的性能开销.
- 在不是严格要求性能时,优先使用动态多态性.
- 可以使用模板方法来实现静态多态性.
总结. 传统过程化设计中,策略依赖于细节.这样细节的改变影响了策略.
OOP中,客户拥有服务接口,同时细节和策略都依赖于抽象.这是OO的标志.
DIP对可重用的框架是必须的.同时它对于构建对应变化富有弹性的代码也是非常重要的.