3. 依赖倒置原则(Dependence Inversion Principle,DIP)

3.1 定义

(1)要依赖抽象不要依赖具体的实现类。简单的说就是对抽象(或接口)进行编程,不要依赖实现进行编程,这样就降低了客户与实现模块间的耦合。包含3层含义:

  ①高层模块不应依赖低层模块,两者都应该依赖于抽象

  ②抽象不应该依赖细节

  ③细节应该依赖于抽象

(2)何为“高层模块”和“低层模块”

  ①“低层模块”:每个逻辑的实现都是原子逻辑组成,不可分割的原子逻辑就是低层模块。一般和具体实现相关。

  ②“高层模块”:原子逻辑再组装就是高层模块,一般和业务逻辑相关。如客户端。

(3)何为“倒置”

  ①“依赖正置”:就是类间的依赖是实实在在的实现类间的依赖,也就是面向实现编程,这符合人的正常思维。如我们开奔驰车就是依赖奔驰车,使用笔记本电脑就直接依赖笔记本电脑。

  ②“依赖倒置”:编程是对现实世界事物进行抽象,然后我们根据系统设计的需要产生了对抽象的依赖,代替了人的传统思维中事物间的依赖,这叫“倒置”。

3.2  依赖实现编程存在的问题及改进

(1)Driver只能开奔驰车!

【编程实验】司机只能看奔驰车

//面向对象设计原则: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 ;
}

(2)解决方案——引入依赖倒置!

  ①通过IDriver和ICar两个接口来类间的耦合,引入依赖倒置原则

  ②汽车提供run方法。司机的职能就是驾驶汽车,必须实现Drive方法。当新增加汽车类时只要该汽车实现了ICar接口,司机就可以开了。

  ③Client是高层业务逻辑,它对低层的依赖是建立在抽象上。

【编程实验】司机可开各类车

//面向对象设计原则:DIP依赖倒置原则
//司机可开任何汽车——依赖抽象/接口 #include <stdio.h> //汽车接口
class ICar
{
public:
virtual void run() = ;
}; //奔驰车类
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) = ; //依赖接口
}; //司机类
class Driver : public IDriver
{
public:
void drive(ICar& car) //实现接口
{
car.run();
}
}; int main()
{
Driver zhangSan;
Benz benz;
BWM bwm; //张三开奔驰车
zhangSan.drive(benz); //张三开宝马
zhangSan.drive(bwm); return ;
}

3.3 依赖的3种写法(详见第1章)

(1)构造函数传递依赖对象

(2)Setter方法传递赖对象

(3)通过接口声明依赖对象(如编程实验2)

3.4 最佳实践

(1)每个类尽量都有接口或抽象类,或两者都有,这是依赖倒置的基本要求,有了抽象才可能依赖倒置

(2)声明变量时尽量用接口或抽象类,实例化再用具体的类

(3)任何类都不应该从具体的类派生(或者继承自具体类时不应超过两层)

(4)尽量不要覆盖基类己经实现的的方法。

(5)结合里氏替换原则,对子类进行设计。以便实现类能准确的实现业务逻辑又不违反LSP原则。

第2章 面向对象的设计原则(SOLID):3_依赖倒置原则(DIP)的更多相关文章

  1. 【面向对象设计原则】之依赖倒置原则(DIP)

    依赖倒转原则(Dependency Inversion  Principle, DIP):抽象不应该依赖于细节,细节应当依赖于抽象.换言之,要针对抽象(接口)编程,而不是针对实现细节编程. 开闭原则( ...

  2. C#软件设计——小话设计模式原则之:依赖倒置原则DIP

    前言:很久之前就想动笔总结下关于软件设计的一些原则,或者说是设计模式的一些原则,奈何被各种bootstrap组件所吸引,一直抽不开身.群里面有朋友问博主是否改行做前端了,呵呵,其实博主是想做“全战”, ...

  3. 《设计模式》-原则三:依赖倒置原则(DIP)

    这几天晚上回来都去玩了!没有坚持学习.真的好惭愧! 非常自责 后面一定要坚持 一气呵成  争取每天学一点,把这个学完. 今天主要是看了一下  设计模式中的 原则三: 依赖倒置原则(DIP) 官方是这样 ...

  4. 【设计模式六大原则3】依赖倒置原则(Dependence Inversion Principle)

      定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成.这种场景下,类 ...

  5. 面象对象设计原则之五:依赖倒置原则(The Dependency Inversion Principle,DIP)

    如果说开闭原则是面向对象设计的目标的话,那么依赖倒转原则就是面向对象设计的主要实现机制之一,它是系统抽象化的具体实现.依赖倒转原则是Robert C. Martin在1996年为“C++Reporte ...

  6. 依赖倒置原则(Dependency Inversion Principle)

    很多软件工程师都多少在处理 "Bad Design"时有一些痛苦的经历.如果发现这些 "Bad Design" 的始作俑者就是我们自己时,那感觉就更糟糕了.那么 ...

  7. 北风设计模式课程---依赖倒置原则(Dependency Inversion Principle)

    北风设计模式课程---依赖倒置原则(Dependency Inversion Principle) 一.总结 一句话总结: 面向对象技术的根基:依赖倒置原则(Dependency Inversion ...

  8. C++ 设计模式 依赖倒置原则 简单示例

    C++ 设计模式 依赖倒置原则 简单示例 /** * 依赖倒置原则(Dependency Inversion Principle) * 依赖于抽象(接口),不要依赖具体的实现(类),也就是针对接口编程 ...

  9. 第2章 面向对象的设计原则(SOLID):6_开闭原则

    6. 开闭原则(Open Closed Principle,OCP) 6.1 定义 (1)一个类应该对扩展开放,对修改关闭.要求通过扩展来实现变化,而且是在不修改己有的代码情况下进行扩展,也不必改动己 ...

随机推荐

  1. Linux 安装 Nginx

    1. nginx的安装: 开始学习如何安装nginx,首先安装必要的软件: # yum install libtool # yum install -y gcc-c++ # yum install z ...

  2. NYOJ 58 最少步数

    最少步数 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 这有一个迷宫,有0~8行和0~8列: 1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 ...

  3. ASP.NET数据绑定技术

    1.DataBinder.Eval()方法 DataBinder.Eval()方法是ASP.NET框架支持的一个静态方法,用来计算Late_Bound(后期绑定)数据绑定表达式,并随时将结果转换为字符 ...

  4. 其他图片和webP之间相互转换

    WebP 是谷歌研发出来的一种图片数据格式,它是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8.根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% ...

  5. SharedPreference.Editor的apply和commit方法异同

    这两个方法的区别在于: 1. apply没有返回值而commit返回boolean表明修改是否提交成功 2. apply是将修改数据原子提交到内存, 而后异步真正提交到硬件磁盘, 而commit是同步 ...

  6. android在Data目录内置可删除的APP

    一.准备工作:make_ext4fs.mkuserimg.sh.simg2img,把它们跟要修改的 .img.ext4(或.img)文件放置到同一个目录下 二.转换源文件为img格式( .img则略过 ...

  7. iOS--页面间的代理传值(属性、代理(委托)、代码块、单例、通知)

    (一)属性传值 (二)代理(委托)传值 代理传值 适用于 反向传值 (从后往前传) 1.1 创建协议 及协议方法 在反向传值的页面(SecondViewController)中 1.2 创建协议类型的 ...

  8. iOS网络-04-大文件下载

    大文件下载注意事项 若不对下载的文件进行转存,会造成内存消耗急剧升高,甚至耗尽内存资源,造成程序终止. 在文件下载过程中通常会出现中途停止的状况,若不做处理,就要重新开始下载,浪费流量. 大文件下载的 ...

  9. Cocos2d-X-3.0之后的版本的环境搭建

    由于cocos2d游戏开发引擎更新十分频繁,官方文档同步不够及时和完善.所以不要照着官方文档来照做生成工程. <点击图片就能进入网站> 具体的步骤: 1.获取cocos2d-X的源码v3. ...

  10. 又一个悬而未决的bug被解决

    之所以叫悬而未决,是因为从我第一次见到这个bug,到现在大概已经过了快两年的时间,期间好几次想解决这个问题,但是一直碍于环境和一些技术上的限制,没有解决,直到昨天在一系列的因素作用下,终于解决了这个问 ...