资讯详情

4.3 依赖倒置原则

一. 依靠倒置原则的定义

1.核心思想

依靠倒置原则(Dependence Inversion Principle,DIP)

*1.高层模块 不应该依赖 低层模块, 两者都要靠抽象;

*2.抽象 不应该依赖 细节, 细节 应该依赖 抽象; 接口和抽象价值在于设计;

*3.依赖倒转(倒置)的中心思想是面向接口编程,实现接口而不是继承或调用实现;

*4.依靠倒转原则的设计理念:

通过抽象发生模块间的依赖,实现类间无直接依赖关系,其依赖关系是通过接口或抽象类产生的;

相对于细节的多变性,抽象的东西要稳定的多,以抽象为基础搭建的框架比以细节为基础

结构要稳定得多,在java抽象是指接口或抽象类(抽象战略方法),细节是具体的实现类(多变战术实现);

使用接口或抽象类的目的是制定规范(设计),而不涉及任何具体操作,将处理细节的任务交给子实现类;

2.注意事项和细节

1)注意事项

*1.低层模块应尽可能抽象或接口,或两者都有,程序稳定性更好;

*2.变量的声明类型应尽可能抽象或接口,以便在变量参考和实际对象之间存在缓冲层,有利于程序的扩展和优化;

*3.继承时遵循里氏替代原则;

2)注意细节

*1.高层模块不应依赖低层模块,两者都应依赖抽象;

*2.抽象不应依赖细节(具体实现类);

*3.细节(具体实现类)应依赖抽象(实现抽象);

二.依靠倒置原则的作用

1. 依靠倒置原理可以降低类间耦合。

2. 依靠倒置原则可以提高系统的稳定性。

3. 依靠倒置原则可以降低并行开发的风险。

4. 依靠倒置原则可以提高代码的可读性和可维护性。

三.依靠倒置实现模式

依靠倒置原则的目的是通过面向接口的编程来减少类之间的耦合,因此只要我们在实际编程中遵循以下四点,我们就可以在项目中满足这一规则。

1. 尽量提供接口或抽象类,或两者都有;

2. 变量声明类型尽量为接口或抽象类;

3. 任何类别都不应从具体类别中衍生;

4. 尽量遵循里氏替代原则,使用继承;

四.依赖关系传递的三种方式

*1.通过构造函数传输依赖对象:通过构造方法传输接口 (例如,构造函数的形参是抽象的或接口 Entry(Interface iView);)

*2.通过setter传递依赖对象的方法:通过setter方法传输接口实现类(setListener(Interface iView){this.iView=iView;} )

*3.接口声明实现依赖对象:通过方法直接传输接口

示例 IOpenAndClose 依赖 ITV

//TV接口 interface ITV{ fun play()}  //实现类 class ChangHong : ITV {     override fun play() {         println("长虹电视机打开了")     } } /**  * 依赖关系传递的三种方式  * 1.基于接口传输 : 接口回调传值  * 2.基于结构传输方法  * 3.setter方式传递  */ //方法1:依赖于接口传输 fun func1(){     val changHong:ChangHong= ChangHong()     val openAndClose:OpenAndClose= OpenAndClose()     openAndClose.open(changHong) } interface IOpenAndClose{     fun open(tv:ITV)//抽象方法,接收接口 } //实现类,通过传输接口实现类调用接口法 class OpenAndClose : IOpenAndClose{     override fun open(tv: ITV) { tv.play() } }  //方式2 通过构造方法依赖传递 fun func1(){     val changHong:ChangHong= ChangHong()     val openAndClose: OpenAndClose = OpenAndClose(changHong)     openAndClose.open() } interface IOpenAndClose{     fun open()//抽象方法 } ///通过实现构造器传输接口 依赖 class OpenAndClose(tv:ITV) : IOpenAndClose{     private val mTv: ITV = tv     override fun open() {         mTv.play()     } }  /方式3:通过Setter方法 依赖 fun func3(){     val changHong: ChangHong = ChangHong()     val openAndClose: OpenAndClose = OpenAndClose()     openAndClose.setTv(changHong)     openAndClose.open() } interface IOpenAndClose {     fun open()//抽象方法     fun setTv(tv: ITV) }  //通过实现类调用setter传递依赖的方法 class OpenAndClose : IOpenAndClose {     private var mTv: ITV? = null     override fun open() {         mTv? = null     override fun open() {         mTv?.play()     }     override fun setTv(tv: ITV) {         mTv = tv     } }  

五.实例

让细节的具体实现类依赖于(使用)抽象类或接口,而不是让接口或抽象类依赖于细节的具体实现;在接收信息功能程序中依赖倒置原则的应用:

1.类图

2.代码示例

object DependenceInversion {     @JvmStatic     fun main(args: Array<String>) {         val person = Person()         person.receive(Email())         person.receive(WeChat())     } } /**  * 需求: 完成Person接收信息的功能  * 方式1分析  * 1.简单,通过建立具体的新闻类别,比如: Email WeChat Sms转移自己的getInfo方法  * 2.问题:这种实现会因需求而增加新的类别,person还应增加相应的接收方法  * 3.解决方案:引入抽象界面IReceiver,表示接收者,这样Person类与接口IReceiver建立依赖  * 4.因为Email,WeChat 等都属于IReceiver他们各自实现了接收范围IReceiver接口,这样,我们就符合依赖倒置的原则  * @author xuezhihui  * @date 2020/11/23 20:03  */ open class Person {     //这里Person依赖接口, 传参是接口的实现类     fun receive(receiver: IReceiver?) {         println(receiver?) {         println(receiver?.getInfo())     } } ///信息接收器 interface IReceiver {     fun getInfo(): String? }  //接收E-mail信息 class Email :IReceiver {     override fun getInfo(): String? {         return "Email接收的信息"     } } ///接收微信信息 class WeChat :IReceiver {     override fun getInfo(): String? {         return "WeChat接收的信息"     } } 

程序的运行结果如下:

Email接收的信息 WeChat接收的信息 

标签: itv液压螺旋连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司