敏捷软件开发:原则、模式与实践——第11章 DIP:依赖倒置原则
第11章 DIP:依赖倒置原则
DIP:依赖倒置原则:
a.高层模块不应该依赖于低层模块。二者都应该依赖于抽象。
b.抽象不应该依赖于细节。细节应该依赖于抽象。
11.1 层次化
下图展示了一个简单的层次化方案:
高层的Policy层使用了低层的Mechanism层,而Mechanism层又使用了更细节的Utility层。它存在一个隐伏的错误特征,那就是:Policy层对于其下一直到Utility层的改动都是敏感的。依赖关系是传递的。
下图展示了一个更为合适的模型:
每个较高层次都为它所需要的服务声明一个抽象接口。较低层次实现了这些接口。每个高层类都通过该接口使用下一层。这样高层就不依赖于低层。低层反而依赖于高层中声明的抽象服务接口。
11.1.1 倒置的接口所有权
这里的倒置不仅仅是依赖关系的倒置,它也是接口所有权的倒置。我们通常会认为工具库应该拥有它们自己的接口。但是当应用了DIP时,我们发现往往是客户拥有抽象接口,而它们的服务则从这些接口派生。
这就是著名的Hollywood原则:“Don't call us, we'll call you.(不要调用我们,我们会调用你。)” 低层模块实现了在高层模块中声明并被高层模块调用的接口。
这里所说的所有权仅仅是指接口是随拥有它们的客户程序发布的,而非实现它们的服务器程序。接口和客户程序位于同一个包或者库中。这就迫使服务器程序库或者包依赖于客户程序库或者包。
当然,有时我们会不想让服务器程序依赖于客户程序,特别是当有多分客户程序但是服务器却仅有一份时。在这种情况下,客户程序必须得遵循服务接口,并把它发布到一个独立的包中。
11.1.2 依赖于抽象
程序中所有的依赖关系都应该终止于抽象类或者接口。
- 任何变量都不应该持有一个指向具体类的引用。
- 任何类都不应该从具体类派生。
- 任何方法都不应该重写它的任何基类中已经实现了的方法。
当然,每个程序都会有违反该启发规则的情况。有时必须创建具体类的实例,而创建这些实例的模块将会依赖于它们。此外,该启发规则对于那些虽然是具体但却稳定的来来说似乎不大合理。如果一个具体类不太会改变,并且也不会创建其他类似的派生类,那么依赖于它并不会造成损害。
比如,在大多数系统中,描述字符串的类都是具体的。例如,在C#中的String。该类是稳定的。也就是说,它不太会改变。因此,直接依赖于它不会造成伤害。
如果一个不稳定的类的接口必须变化是,这个变化一定会影响到表示该类的抽象接口。这种变化破坏了由抽象接口维系的隔离性。
可见,该启发规则对问题的考虑有点儿简单了。另一方面,如果看得更远一点,认为是客户模块或者层来声明它们需要的服务接口,那么仅当客户需要时才会对接口进行改变。这样,改变实现抽象接口的类就不会影响到客户。
结论
使用传统的过程化程序设计所创建出来的依赖关系结构、策略是依赖于细节的。这是糟糕的,因为这样会使策略受到细节的改变的影响。面向对象的程序设计倒置了依赖关系结构,使得细节和策略都依赖于抽象,并且常常是客户程序拥有服务接口。
事实上,这种依赖关系倒置正是好的面向对象设计的标志所在。使用何种语言编程是无关紧要的。如程序的依赖关系是倒置的,它就是面向对象的设计。如果程序的依赖关系不是倒置的,它就是过程化的设计。
摘自:《敏捷软件开发:原则、模式与实践(C#版)》Robert C.Martin Micah Martin 著
转载请注明出处:
作者:JesseLZJ
出处:http://jesselzj.cnblogs.com
敏捷软件开发:原则、模式与实践——第11章 DIP:依赖倒置原则的更多相关文章
- 六大设计原则(三)DIP依赖倒置原则
依赖倒置原则DIP(Dependence Inversion Principle) 依赖倒置原则的含义 高层模块不能依赖低层模块,二者都应该依赖其抽象. 抽象不应该依赖于细节. 细节应该依赖抽象. 什 ...
- DIP依赖倒置原则
一.定义 1.高层模块不应该依赖低层模块,二者都应该依赖抽象 2.抽象不应该依赖于细节.细节应该依赖于抽象 二.层次化 1.简单介绍 结构良好的面向对象架构都具有清晰的层次定义,每个层次通过一个定义良 ...
- 九 DIP 依赖倒置原则
首先看定义: 1.高层模块不依赖于低层模块,两者都应该依赖于抽象层 2.抽象不能依赖于细节,细节必须依赖于抽象 首先,模块是个抽象的概念,可以大到一个系统中的子系统作为一个模块,也可以是某个子系统中的 ...
- 【Scrum】-NO.40.EBook.1.Scrum.1.001-【敏捷软件开发:原则、模式与实践】- Scrum
1.0.0 Summary Tittle:[Scrum]-NO.40.EBook.1.Scrum.1.001-[敏捷软件开发:原则.模式与实践]- Scrum Style:DesignPattern ...
- 《敏捷软件开发-原则、方法与实践》-Robert C. Martin读书笔记(转)
Review of Agile Software Development: Principles, Patterns, and Practices 本书主要包含4部分内容,这些内容对于今天的软件工程师 ...
- 敏捷软件开发_实例2<四>
敏捷软件开发_实例2 上一章中对薪水支付案例的用例和类做了详细的阐述,在本篇会介绍薪水支付案例包的划分和数据库,UI的设计. 包的划分 一个错误包的划分 为什么这个包是错误的: 如果对classifi ...
- [设计模式]<<设计模式之禅>>关于依赖倒置原则
依赖倒置原则(Dependence Inversion Principle,DIP)这个名字看着有点别扭,“依赖”还“倒置”,这到底是什么意思?依赖倒置原则的原始定义是 High level modu ...
- ZT 3.1 依赖倒置原则的定义
设计模式精解-GoF 23 种设计模式解析附 C++实现源码http://www.mscenter.edu.cn/blog/k_eckelP58 Template 模式获得一种反向控制结构效果,这也是 ...
- 依赖倒置原则(Dependency Inversion Principle)
很多软件工程师都多少在处理 "Bad Design"时有一些痛苦的经历.如果发现这些 "Bad Design" 的始作俑者就是我们自己时,那感觉就更糟糕了.那么 ...
随机推荐
- maven release plugin插件
1.打包版本区别 SNAPSHOT 快照版本(开发阶段,不稳定,容易出现bug)RELEASE 正式版本(外部依赖使用阶段,稳定,很少出现bug)Tag :标记每次代码提交的版本(比较稳定,类似分支) ...
- iframe有哪些缺点?
iframe会阻塞主页面的Onload事件: iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载.使用iframe之前需要考虑这两个缺点.如果需要使用ifram ...
- qcow2磁盘加密及libvirt访问
1.创建qcow2加密磁盘[root@Coc-5 test_encrypt]# qemu-img convert -f qcow2 -O qcow2 -o encryption template_ ...
- Change R source code
If you'd like to simply test out the effect of that change in an interactive R session, you can do s ...
- [Z] 将samba共享文件夹映射到linux的目录下
Linux系统下访问远程共享资源 使用mount加载共享目录: -把WinXP机器192.168.16.249上的共享目录test001映射到本地目录/wdl/下. -把Linux机器192.168. ...
- 10.Redis 性能测试
转自:http://www.runoob.com/redis/redis-tutorial.html Redis 性能测试是通过同时执行多个命令实现的. 语法 redis 性能测试的基本命令如下: r ...
- Zabbix 监控页面中文乱码
问题描述: 如题,我相信大多数人都遇到过这个问题,Zabbix 监控图 中文乱码. 解决这个问题也很简单:( Zabbix 网页目录中缺少字体 ) 1.打开 Windows 的 C:\Windows\ ...
- EF中关系映射问题
一对一,和一对多的简单问题就部说了,直接来多对多这样的问题吧. 首现关系映射为这样的: /// <summary> /// 对应数据库中dbo.Address表 /// </summ ...
- angularjs学习访问服务器(5)
(1) 后台AngularController.java代码 package com.amy.controller; import java.util.ArrayList; import java.u ...
- onload函数和自执行函数的区别(jquery API网址:http://jquery.cuishifeng.cn/)
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...