连载:面向对象葵花宝典:思想、技巧与实践(34) - DIP原则
来源:互联网 发布:sql数据类型转换 编辑:程序博客网 时间:2024/06/01 09:12
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 {@Overridepublic void accelerate() {//加速非常快System.out.println("Benz accelerate: very fast !!"); }@Overridepublic void shift() {//自动挡System.out.println("Benz shift: automatic transmission !!"); }@Overridepublic void steer() {//非常平稳System.out.println("Benz steer: very smooth,ESP && DSC && VSC !!"); }@Overridepublic void brake() {//刹车辅助系统System.out.println("Benz steer: ABS && EBA && BAS && BA !!"); }}
【Ford】
package com.oo.oop.dip;/** * 福特,实现了ICar接口,对应DIP中的“低层依赖抽象层” * */public class Ford implements ICar {@Overridepublic void accelerate() {//加速快System.out.println("Ford accelerate: fast !!"); }@Overridepublic void shift() {//手自一体变速器System.out.println("Ford shift: Tiptronic transmission !!"); }@Overridepublic void steer() {//平稳System.out.println("Ford steer: smooth,ESP !!"); }@Overridepublic void brake() {//刹车辅助系统System.out.println("Ford steer: ABS && EBA &!!"); }}
【Chery】
package com.oo.oop.dip;/** * 奇瑞,实现了ICar接口,对应DIP中的“低层依赖抽象层” * */public class Chery implements ICar {@Overridepublic void accelerate() {//加速慢System.out.println("Chery accelerate: slow !!"); }@Overridepublic void shift() {//手动挡System.out.println("Chery shift: manual transmission !!"); }@Overridepublic void steer() {//平稳System.out.println("Chery steer: smooth,ESP && DSC !!"); }@Overridepublic void brake() {//刹车辅助系统System.out.println("Chery steer: only ABS !!"); }}
================================================
转载请注明出处:http://blog.csdn.net/yunhua_lee/article/details/30749311================================================
- 连载:面向对象葵花宝典:思想、技巧与实践(34) - DIP原则
- 连载:面向对象葵花宝典:思想、技巧与实践(28) - 设计原则:内聚&耦合
- 连载:面向对象葵花宝典:思想、技巧与实践(30) - SRP原则
- 连载:面向对象葵花宝典:思想、技巧与实践(31) - OCP原则
- 连载:面向对象葵花宝典:思想、技巧与实践(32) - LSP原则
- 连载:面向对象葵花宝典:思想、技巧与实践(33) - ISP原则
- 连载:面向对象葵花宝典:思想、技巧与实践(35) - NOP原则
- 连载:面向对象葵花宝典:思想、技巧与实践(36) - 设计原则如何用?
- 连载:面向对象葵花宝典:思想、技巧与实践(39) - 设计原则 vs 设计模式
- 连载:面向对象葵花宝典:思想、技巧与实践(3) - 面向过程 vs 面向对象
- 连载:面向对象葵花宝典:思想、技巧与实践(3) - 面向过程 vs 面向对象
- 连载:面向对象葵花宝典:思想、技巧与实践(3) - 面向过程 vs 面向对象
- 连载:面向对象葵花宝典:思想、技巧与实践(3) - 面向过程 vs 面向对象
- 连载:面向对象葵花宝典:思想、技巧与实践(2) - 面向对象语言发展历史
- 连载:面向对象葵花宝典:思想、技巧与实践(14) - 面向对象开发技术流程
- 连载:面向对象葵花宝典:思想、技巧与实践(2) - 面向对象语言发展历史
- 连载:面向对象葵花宝典:思想、技巧与实践(14) - 面向对象开发技术流程
- 连载:面向对象葵花宝典:思想、技巧与实践(2) - 面向对象语言发展历史
- exists 与 in 的区别
- Properties类读写.properties配置文件
- Mac OSX & iOS 操作系统学习笔记01——OSX进化史
- How to sensibly split an array around an object
- 基于RDP协议的开源rdesktop简介
- 连载:面向对象葵花宝典:思想、技巧与实践(34) - DIP原则
- SQL查询案例:多行转换为一行
- [LeetCode] Linked List Cycle II
- CVPR14与图像视频检索相关的论文
- Google发布内涵图 暗示Android 5.0系统将至
- 图像检索中为什么仍用BOW和LSH
- 使用mac地址ssh
- N! Last non zero
- Windows 核心编程 第三章 笔记