连载:面向对象葵花宝典:思想、技巧与实践(34) - DIP原则
DIP,dependency inversion principle,中文翻译为“依赖倒置原则”。
DIP是大名鼎鼎的Martin大师提出来的。他在1996 5月的C++ Reporter发表“ The Dependency Inversion Principle”的文章具体阐述了DIP原则,而且在他的经典著作《 Agile Software Development, Principles, Patterns》(中文翻译为:敏捷软件开发:原则、模式与实践)、《Practices, and Agile Principles, Patterns, and Practices in C#》(中文翻译为:敏捷软件开发:原则、模式与实践(C#版))中详解了DIP原则。
DIP原则主要有两点含义:
1) 高层模块不应该直接依赖低层模块。两者都应该依赖抽象层。
2) 抽象不能依赖细节。细节必须依赖抽象。
尽管DIP原则的解释很清楚。但要真正理解也不那么简单,由于有几个关键的术语都比較抽象,我们须要更具体的解析:
1)什么是模块?
英文中用到了module、component,但我们这是在讲类的设计原则,为什么要把DIP拉进来呢?
事实上Martin大师仅仅是讲一个设计原则而已,这个原则能够应用到软件系统不同的层级。
比如:站在架构层的角度,模块能够指子系统subsystem
站在子系统的角度。模块能够指module,component
站在模块的角度:模块能够指类
所以说。这里的模块应该是一个广义的概念,而不是狭义的软件系统里各个子模块。
2)什么是依赖?
这里的依赖相应到具体的面向对象领域事实上包括几个内容:
高层模块“依赖”低层模块:指高层模块须要调用低层模块的方法。
高层模块依赖抽象层:指高层模块基于抽象层编程;
低层模块依赖抽象层:指低层模块继承(inheritance)或者实现(implementation)抽象层。
细节依赖抽象:事实上和上一个依赖是同一个意思;
所以说,大师就是大师啊,一个简简单单的“依赖”将各种情况都概括进来了,仅仅是苦了我们这些平庸人,要么导致无法理解,要么导致理解错误:(
我们以一个简单例子来详解这些依赖,例子包括一个Player类,代表玩家。ICar接口。代表汽车;Benz、Ford、Chery代表具体的汽车,具体的代码例如以下
【Player】
- package com.oo.oop.dip;
- /**
- * 玩家,相应DIP中的“高层模块”
- *
- */
- public class Player {
- /**
- * 开福特
- * 不好的依赖:相应DIP中的“高层模块依赖低层模块”,Player直接使用了Ford类对象作为參数,Ford类改动,Player类【须要】又一次编译測试
- */
- public void play(Ford car)
- {
- car.accelerate();
- car.shift();
- car.steer();
- car.brake();
- }
- /**
- * 开奔驰
- * 不好的依赖:相应DIP中的“高层模块依赖低层模块”。Player直接使用了Benz类对象作为參数。Benz类改动,Player类【须要】又一次编译測试
- */
- public void play(Benz car)
- {
- car.accelerate();
- car.shift();
- car.steer();
- car.brake();
- }
- /**
- * 开奇瑞
- * 不好的依赖:相应DIP中的“高层模块依赖低层模块”,Player直接使用了Chery类对象作为參数,Chery类改动。Player类【须要】又一次编译測试
- */
- public void play(Chery car)
- {
- car.accelerate();
- car.shift();
- car.steer();
- car.brake();
- }
- /**
- * 开车
- * 好的依赖: 相应DIP中的“高层模块依赖抽象层”,Player依赖ICar接口。不须要知道具体的车类型。Ford、Benz、Chery类改动。Player类【不须要】又一次编译測试。仅仅有ICar改动的时候Player才须要改动
- */
- public void play(ICar car)
- {
- car.accelerate();
- car.shift();
- car.steer();
- car.brake();
- }
- }
【ICar】
- package com.oo.oop.dip;
- /**
- * 汽车接口,相应DIP中的抽象层
- */
- public interface ICar {
- /**
- * 加速
- */
- public void accelerate();
- /**
- * 换挡
- */
- public void shift();
- /**
- * 转向
- */
- public void steer();
- /**
- * 刹车
- */
- public void brake();
- }
【Benz】
- package com.oo.oop.dip;
- /**
- * 奔驰,实现了ICar接口,相应DIP中的“低层依赖抽象层”
- *
- */
- public class Benz implements ICar {
- @Override
- public void accelerate() {
- //加速很快
- System.out.println("Benz accelerate: very fast !!");
- }
- @Override
- public void shift() {
- //自己主动挡
- System.out.println("Benz shift: automatic transmission !!");
- }
- @Override
- public void steer() {
- //很平稳
- System.out.println("Benz steer: very smooth,ESP && DSC && VSC !!");
- }
- @Override
- public void brake() {
- //刹车辅助系统
- System.out.println("Benz steer: ABS && EBA && BAS && BA !!");
- }
- }
【Ford】
- package com.oo.oop.dip;
- /**
- * 福特,实现了ICar接口,相应DIP中的“低层依赖抽象层”
- *
- */
- public class Ford implements ICar {
- @Override
- public void accelerate() {
- //加速快
- System.out.println("Ford accelerate: fast !!");
- }
- @Override
- public void shift() {
- //手自一体变速器
- System.out.println("Ford shift: Tiptronic transmission !!");
- }
- @Override
- public void steer() {
- //平稳
- System.out.println("Ford steer: smooth。ESP !!");
- }
- @Override
- public void brake() {
- //刹车辅助系统
- System.out.println("Ford steer: ABS && EBA &!!");
- }
- }
【Chery】
- package com.oo.oop.dip;
- /**
- * 奇瑞。实现了ICar接口,相应DIP中的“低层依赖抽象层”
- *
- */
- public class Chery implements ICar {
- @Override
- public void accelerate() {
- //加速慢
- System.out.println("Chery accelerate: slow !!");
- }
- @Override
- public void shift() {
- //手动挡
- System.out.println("Chery shift: manual transmission !!");
- }
- @Override
- public void steer() {
- //平稳
- System.out.println("Chery steer: smooth。ESP && DSC !!");
- }
- @Override
- public void brake() {
- //刹车辅助系统
- System.out.println("Chery steer: only ABS !!");
- }
- }
================================================
转载请注明出处:http://blog.csdn.net/yunhua_lee/article/details/30749311
================================================
连载:面向对象葵花宝典:思想、技巧与实践(34) - DIP原则的更多相关文章
- 连载:面向对象葵花宝典:思想、技巧与实践(28) - 设计原则:内聚&耦合
前面通过实例解说了一个一环扣一环的面向对象的开发流程:用例模型 -> 领域模型 -> 设计模型(类模型 + 动态模型),解答了面向对象怎样做的问题.接下来我们就要讲"怎样做好面向 ...
- 连载:面向对象葵花宝典:思想、技巧与实践(33) - ISP原则
ISP,Interface Segregation Principle,中文翻译为"接口隔离原则". 和DIP原则一样,ISP原则也是大名鼎鼎的Martin大师提出来的,他在19 ...
- IT第二十天 - 面向对象编程思想、抽象类、异常处理、程序操作日志记录、本周总结 ★★★
IT第二十天 上午 面向对象编程思想 1.组装电脑的设计: (1)电脑的组成:显示器+机箱 (2)机箱的组成:电源+主板+硬盘 (3)主板所包含的部件:cpu+内存+PCI接口+usb接口 (4)PC ...
- 黑马程序员——OC语言基础语法 面向对象的思想
Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结)(一)基础语法 1)关键字 @interface.@implementati ...
- Java面向对象的思想
面向对象的思想 1.面向对象的思想的特点: ①符合人们的日常思考习惯 ②能将复杂的问题简单化 ③将原来的执行者变为了现在的指挥者 面向对象的思想,所谓的对象,其实就是实体.对于实物的描述,通常有两个方 ...
- 面向对象编程思想(OOP)
本文我将从面向对象编程思想是如何解决软件开发中各种疑难问题的角度,来讲述我们面向对象编程思想的理解,梳理面向对象四大基本特性.七大设计原则和23种设计模式之间的关系. 软件开发中疑难问题: 软件复杂庞 ...
- U3D 飞机大战(MVC模式)解析--面向对象编程思想
在自己研究U3D游戏的时候,看过一些人的简单的游戏开发视频,写的不错,只是个人是java web 开发的人,所以结合着MVC思想,对游戏开发进行了一番考虑. 如果能把游戏更加的思想化,分工化,开发便明 ...
- OC - 1.面向过程和面向对象的思想对比
一.面向过程 1> 思想 面向过程是一种以过程为中心的最基础编程思想,不支持面向对象的特性. 面向过程是一种模块化程序设计方法 2> 开发方法 面向过程的开发方法是以过程(也可以说是模块) ...
- .net的自定义JS控件,运用了 面向对象的思想 封装 了 控件(.net自定义控件开发的第一天)
大家好!我叫刘晶,很高兴你能看到我分享的文章!希望能对你有帮助! 首先我们来看下几个例子 ,就能看到 如何 自定义控件! 业务需求: 制作 一个 属于 自己的 按钮 对象 ,然后 像 ...
随机推荐
- jquery实现点击进入新的页面。(jquery实现超链接)
<script src="jquery-1.9.1.min.js" type="text/javascript"></script> & ...
- golang 并发锁的陷阱
错误代码示例 package main import ( "sync" "strconv" "fmt" ) type Node struct ...
- 逻辑回归(Logistic Regression)推导
出自BYRans博客:http://www.cnblogs.com/BYRans/ 本文主要讲解分类问题中的逻辑回归.逻辑回归是一个二分类问题. 二分类问题 二分类问题是指预测的y值只有两个取值(0或 ...
- Jmeter各组件介绍 及 使用
本篇主要讲述Jmeter的各个组件及简单使用,其中包括以下内容: 一.线程组二.逻辑控制器三.配置元件四.定时器五.后置处理器六.断言七.监听器 八.参数化 网上大神整理的链接:http://blog ...
- 对Oracle 、SQL Server、MySQL、PostgreSQL数据库优缺点分析
对Oracle .SQL Server.MySQL.PostgreSQL数据库优缺点分析 Oracle Database Oracle Database,又名Oracle RDBMS,或简称Oracl ...
- 携程transform放大效果
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Javascript(IE快捷键操作),ASP技巧
1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键 <table border oncontextmenu ...
- Java学习4_一些基础4_输入输出_16.5.7
读取输入: 想从控制台进行输入,首先需要构造一个Scanner对象,并与“标准输入流”System.in关联. Scanner in=new Scanner(System.in); String na ...
- HDU_1180_诡异的楼梯_BFS
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1180 诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others) Me ...
- 创建一个 Vue 的实例
每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue({ // 选项 }) 选项:el.data.methods el: 类型: ...