依赖倒置
依赖倒置 Dependence Inversion Principle DIP.
High level modules shouldnot depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details. Details should depend upon abstractions。
依赖倒置原则的定义:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。
其核心思想是:要面向接口编程,不要面向实现编程。
实现方法
依赖倒置的目的是通过面向接口的编程来降低类间的耦合性,所以稳定的软件架构设计应该避免依赖易变的具体类,每个类都尽量使用接口或抽象类,任何类都不从具体类派生。
如何正确使用:
- 不引用易变的具体实现类。无论静态语言还是动态语言都引用抽象接口类,对对象的创建增加约束,比如使用抽象工厂模式创建对象。
- 不从易变的具体类实现派生
- 不覆盖具体实现的方法。当依赖某对象时,对于父类的具体方法都进行覆盖重写
- 不提任何具体实现和易变类的名字
以下Demo主要通过构造函数方式实现依赖倒置:
class Customer {
constructor(
private readonly shop: Shopping
){}
async goShop() {
return console.log(this.shop.sell());
}
}
class Shopping {
sell(){
return '小卖部卖东西...';
}
}
(()=>{
const shop = new Shopping();
const cust = new Customer(shop);
cust.goShop();
})();
依赖倒置的优点
- 可以降低类之间的耦合性
- 提高系统的稳定性
- 减少并行开发引发的风险
- 提高代码的可读性和可维护性
开闭原则和依赖倒置原则区别
- 开闭原则:开启扩展,关闭修改;
- 依赖倒置:抽象不依赖具体,具体应依赖抽象
- 都是对类/接口的设计
软件设计第一课中讲述:一个好的软件设计者和架构师应该努力去减少接口的易变形,应尝试对于实现类增加函数而不改变接口。这也是我们使用DIP的原因:依赖不变的抽象,扩展具体实现。