一、定义
依赖倒转原则(Dependency Inversion Principle, DIP):抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程。
依赖倒置原则是实现后面的开闭原则的重要手段
二、特点
依赖倒转原则要求我们在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情。
为了确保该原则的应用,一个具体类应当只实现接口或抽象类中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增
加的新方法。
在引入抽象层后,系统将具有很好的灵活性,在程序中尽量使用抽象层进行编程,而将具体类写在配置文件中,这样一来,如果系统行为发生变化,只需要对抽象层进行扩展,并修改配置文件,而无须修改原有系统的源代码,在不修改的情况下来扩展系统的功能,满足开闭
原则的要求。
在实现依赖倒转原则时,我们需要针对抽象层编程,而将具体类的对象通过依赖注入(DependencyInjection, DI)的方式注入到其他对象中,依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。常用的注入方式有三种,分别是:构造注入,设值注入(Setter注入)和接口注入。构造注入是指通过构造函数来传入具体类的对象,设值注入是指通过Setter方法来传入具体类的对象,而接口注入是指通过在接口中声明的业务方法来传入具体类的对象。这些方法在定义时使用的是抽象类型,在运行时再传入具体类型的对象,由子类对象来覆盖父类对象
三、案例
公司开发人员在开发某CRM系统时发现:该系统经常需要将存储在TXT或Excel文 件中的客户信息转存到数据库中,因此需要进行数据格式转换。在客户数据操作类中将调用 数据格式转换类的方法实现格式转换和数据库插入操作。
(一)初始方案
存在问题
如有时候需要将 TXTDataConvertor改为ExcelDataConvertor,此时,需要修改CustomerDAO的源代码,而且在 引入并使用新的数据转换类时也不得不修改CustomerDAO的源代码,系统扩展性较差,违反 了开闭原则,现需要对该方案进行重构。
(二)DIP优化
由于CustomerDAO针对具体数据转换类编程,因此在增加新的数据转换类或者 更换数据转换类时都不得不修改CustomerDAO的源代码。我们可以通过引入抽象数据转换类 解决该问题,在引入抽象数据转换类DataConvertor之后,CustomerDAO针对抽象类 DataConvertor编程,而将具体数据转换类名存储在配置文件中,符合依赖倒转原则。
对于重构之后的架构中,在CustomerDAO中使用DataConvertor这个抽象类进行操作,如果需要改变CustomerDao中使用其他的DataConvertor的话,可以通过一些方式注入进来,比如set方法、构造器注入等等。如果使用了配置文件进行管理的话,就会更加方便,Spring就是这么处理的