第4章 依赖倒置原则(DIP)
来源:互联网 发布:1080j 最新x站免费域名 编辑:程序博客网 时间:2024/05/19 17:48
一、定义
1、模块间要依赖抽象,不要通过具体的实现类。依赖关系通过接口(抽象)进行编程,这就降低客户与实现模块间的耦
合。(接口或抽象类不依赖于实现类,实现类依赖接口或抽象类 面向接口编程OOD) 包含三层含义:
(1)高层模块不应依赖于低层模块,两者都应该依赖其抽象
(2)抽象不应该依赖细节 (3)细节应该依赖于抽象
2、高层模块和底层模块的概念
(1)低层模块:每个逻辑的实现都是原子逻辑组成,不可分割的原子逻辑就是低层模块。一般和具体的实现相关。
(2)高层模块:原子模块再组装就是高层模块,一般和业务逻辑相关。如客户端。
Java语言中,抽象就是指的是接口或抽象类,两者都不能直接被实例化。
细节就是实现类,实现接口或继承抽象类而产生的类就是细节,特点是直接可以被实例化。
3、何为"倒置"
(1)、依赖正置:类间的依赖是实实在在的实现类间的依赖,面向实现编程,符合人类正常的思维。
(2)、依赖倒置:编程就是对现实世界事务进行抽象,然后根据系统设计产生对抽象的依赖,代替事物间的依赖,称
为"倒置"。
二、依赖实现编程存在的问题及改进
1、Driver只能开奔驰车!
Client是场景类
实验:依赖于实现类,导致司机只能开奔驰车
//面向对象设计原则:DIP依赖倒置原则//司机只能开奔驰车——依赖具体实现#include <stdio.h>//奔驰车类class Benz{public: void run() { printf("Benz Runing...\n"); }};//司机类class Driver{public: //司机类不是依赖于抽象,而是依赖具体的汽车Benz, //导致司机只能开奔驰,不能开其它车的尴尬! void drive(Benz& benz) { benz.run(); } };int main(){ Driver zhangSan; Benz benz; //张三开奔驰车 zhangSan.drive(benz); //参数为Benz类型,张三只会开奔驰! return 0;}有车、有司机,在场景类产生相应的对象。到目前为止,这个司机开奔驰车的项目没有问题。但是业务需求变更永无
休止,技术前进就永无止境,在发生变更的时候才发觉我们设计的程序是否是松耦合。
现在呢,张三司机又想开宝马车,怎么实现呢?设计出现问题:司机类和奔驰车类之间是紧耦合的关系,导致的结果
就是系统的可维护性降低,可读性降低,稳定性低。
2、依赖倒置隆重登场
(1)、好处:减少类间耦合,提高系统的稳定性,提高代码的可维护性和可读性,降低并行开发引起的风险
(2)、通过IDriver和ICar两个接口来实现类间的耦合,引入依赖倒置原则。
接口只是一个抽象化的概念,是对一类事物抽象的描述,具体的代码由相应的实现类来实现。
(3)汽车提供run方法。司机的只能就是驾驶汽车,必须实现Driver方法。新增汽车类只需要实现ICar接口。
(4)ICar接口实现抽象之间的依赖关系,Driver实现类也传入ICar接口,到底是那个Car,需要在高层模块声明。
(5)业务场景类中,抽象不应该依赖细节,也就是抽象(接口)不依赖于实现类(细节),高层模块应用的都是抽象。
编程:司机可以开各种车
//面向对象设计原则:DIP依赖倒置原则//司机可开任何汽车——依赖抽象/接口#include <stdio.h>//汽车接口class ICar{public: virtual void run() = 0;};//奔驰车类class Benz : public ICar{public: void run(){printf("Benz runing...\n");}};//宝马车类class BWM : public ICar{public: void run(){printf("BWM runing...\n");}};//司机接口class IDriver{public: //是司机应该会驾驶汽车 virtual void drive(ICar& car) = 0; //依赖接口};//司机类class Driver : public IDriver{public: void drive(ICar& car) //实现接口 { car.run(); }};int main(){ Driver zhangSan; //引用(对象) 指针(new) Benz benz; BWM bwm; //张三开奔驰车 zhangSan.drive(benz); //张三开宝马 zhangSan.drive(bwm); return 0;}
Client属于高层业务逻辑,对低层的依赖都建立在抽象上,zhangsan都是以IDriver类型进行操作,屏蔽了细节对抽
象的影响。java中,一个变量可以有两种类型:表面类型和实际类型,表面类型是定义的时候赋予的类型,实际类型
是对象的类型。如zhangsan的表面类型是IDriver,实际类型是Driver。
三、依赖的3种写法
1、构造函数传递依赖对象
2、setter方法传递依赖对象
3、通过接口声明依赖对象(接口注入)
四、最佳实践
依赖倒置原则的本质就是通过抽象(抽象类或接口)使各个类或者模块的实现彼此独立,不相互影响,实现模块间的松
耦合。
1、每个类尽量都有接口或者抽象类,或者两者都有,有了抽象才能依赖倒置
2、声明变量时尽量用接口或抽象类,实例化再使用具体的类。变量的表面类型尽量是接口或者抽象类
3、任何类都不应该从具体的类派生(或者继承具体的类不超过两层)
4、尽量不要覆写基类已经实现的方法。如果基类是抽象类,而且这个方法已经实现了,子类尽量不要覆写。类间依
赖的是抽象,覆写抽象方法,对依赖的稳定性产生影响。
5、结合里氏替换原则对子类进行设计。
接口负责定义public属性和方法,并且声明与其他对象的依赖关系。
抽象类负责公共构造部分的实现,实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化。
"面向接口编程"基本上是依赖倒置原则的核心。
- 第4章 依赖倒置原则(DIP)
- DIP依赖倒置原则
- 依赖倒置原则--DIP
- 依赖倒置原则--DIP
- 依赖倒置原则--DIP
- 依赖倒置原则(DIP)
- 依赖倒置原则(DIP)
- 软件设计原则----依赖倒置原则(DIP)
- 软件设计原则----依赖倒置原则(DIP)
- 软件设计原则----依赖倒置原则(DIP)
- 设计模式--------依赖倒置原则(DIP)
- 依赖倒置原则DIP(Dependency-Inversion Principles)
- 依赖倒置原则(DIP) OOP面向对象...
- DIP依赖倒置原则(转)
- 依赖倒置原则(DIP)与依赖反转 区别与联系
- 面向对象设计原则--依赖倒置原则(DIP)
- OOD设计原则之依赖倒置原则(DIP)
- 依赖倒置原则(DIP)批判 -- 称之为本末倒置原则更贴切
- 矩阵乘法在递推问题中的简单应用
- ListView的操作
- 实战低成本服务器搭建千万级数据采集系统
- Git常用命令备忘
- 无符号数减法溢出问题
- 第4章 依赖倒置原则(DIP)
- 数据转化工具
- HDU2018
- C++高精度模版
- Android深入浅出之Binder机制
- git上传github和码云的步骤
- java 中的构造代码块和构造函数以及静态代码块
- 程序调试记录
- 对于张量展开矩阵的理解