第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:依赖倒置原则的更多相关文章

  1. 六大设计原则(三)DIP依赖倒置原则

    依赖倒置原则DIP(Dependence Inversion Principle) 依赖倒置原则的含义 高层模块不能依赖低层模块,二者都应该依赖其抽象. 抽象不应该依赖于细节. 细节应该依赖抽象. 什 ...

  2. DIP依赖倒置原则

    一.定义 1.高层模块不应该依赖低层模块,二者都应该依赖抽象 2.抽象不应该依赖于细节.细节应该依赖于抽象 二.层次化 1.简单介绍 结构良好的面向对象架构都具有清晰的层次定义,每个层次通过一个定义良 ...

  3. 九 DIP 依赖倒置原则

    首先看定义: 1.高层模块不依赖于低层模块,两者都应该依赖于抽象层 2.抽象不能依赖于细节,细节必须依赖于抽象 首先,模块是个抽象的概念,可以大到一个系统中的子系统作为一个模块,也可以是某个子系统中的 ...

  4. 【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 ...

  5. 《敏捷软件开发-原则、方法与实践》-Robert C. Martin读书笔记(转)

    Review of Agile Software Development: Principles, Patterns, and Practices 本书主要包含4部分内容,这些内容对于今天的软件工程师 ...

  6. 敏捷软件开发_实例2<四>

    敏捷软件开发_实例2 上一章中对薪水支付案例的用例和类做了详细的阐述,在本篇会介绍薪水支付案例包的划分和数据库,UI的设计. 包的划分 一个错误包的划分 为什么这个包是错误的: 如果对classifi ...

  7. [设计模式]<<设计模式之禅>>关于依赖倒置原则

    依赖倒置原则(Dependence Inversion Principle,DIP)这个名字看着有点别扭,“依赖”还“倒置”,这到底是什么意思?依赖倒置原则的原始定义是 High level modu ...

  8. ZT 3.1 依赖倒置原则的定义

    设计模式精解-GoF 23 种设计模式解析附 C++实现源码http://www.mscenter.edu.cn/blog/k_eckelP58 Template 模式获得一种反向控制结构效果,这也是 ...

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

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

随机推荐

  1. 大白话系列之C#委托与事件讲解大结局

    声明:本系列非原创,因为太精彩才转载,如有侵权请通知删除,原文:http://www.cnblogs.com/wudiwushen/archive/2010/04/20/1698795.html 今天 ...

  2. 简单租房子实例详解---(session、ajax、json前后台数据处理、分页)

    本次实例我们结合session.ajax.json前后台数据处理.分页技术做一个租房信息系统 一共有五个界面:包括 管理员和用户的登录界面 登录界面的后台 <?php session_start ...

  3. c++ 先序构建二叉树

    二叉树首先要解决构建问题,才能考虑后续的遍历,这里贴出通过先序构建二叉树,同时包含四种二叉树的遍历方法(先序,中序,后序,逐层) 第一.定义BinaryTreeNode 类 #include < ...

  4. DBA_2PC_PENDING (转)

    DBA_2PC_PENDINGOracle会自动处理分布事务,保证分布事务的一致性,所有站点全部提交或全部回滚.一般情况下,处理过程在很短的时间内完成,根本无法察觉到.但是,如果在commit或rol ...

  5. 浅谈OPP

    了解Java或C#等面向对象编程语言的的程序员比较熟悉类和对象以及OOP. 一谈起OOP,就会想起教科书式的OOP概念:封装.继承.多态.粗浅的解释封装就是对数据进行隐藏:继承就是子类继承父类(cla ...

  6. C 语言 - Unicode 解决中文问题

    问题: 打印一句中文 #include <stdio.h> int main() { char str[] = "你好,世界"; printf("%s\n&q ...

  7. MATLAB常用方法技巧总结

    ===================================================================================================M ...

  8. Spring实战之装配Bean

    1.1Spring配置的可选方案 Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系.但是,作为开发人员,你需要告诉Spring要创建哪些bean并且如何将其装配在一起.当 ...

  9. leetcode537

    public class Solution { public string ComplexNumberMultiply(string a, string b) { var aryA = a.Split ...

  10. EXPLAIN sql优化方法(2) Using temporary ; Using filesort

    优化GROUP BY语句   默认情况下,MySQL对所有GROUP BY col1,col2...的字段进行排序.这与在查询中指定ORDER BY col1,col2...类似.因此,如果显式包括一 ...