文档章节

设计模式六大原则(3):依赖倒置原则

zy643208
 zy643208
发布于 2015/05/08 15:19
字数 1363
阅读 2
收藏 0
定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率。

         依赖倒置原则基于这样一个事实:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。在java中,抽象指的是接口或者抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

         依赖倒置原则的核心思想是面向接口编程,我们依旧用一个例子来说明面向接口编程比相对于面向实现编程好在什么地方。场景是这样的,母亲给孩子讲故事,只要给她一本书,她就可以照着书给孩子讲故事了。代码如下:

class Book{
	public String getContent(){
		return "很久很久以前有一个阿拉伯的故事……";
	}
}

class Mother{
	public void narrate(Book book){
		System.out.println("妈妈开始讲故事");
		System.out.println(book.getContent());
	}
}

public class Client{
	public static void main(String[] args){
		Mother mother = new Mother();
		mother.narrate(new Book());
	}
}

运行结果:

妈妈开始讲故事
很久很久以前有一个阿拉伯的故事……

        运行良好,假如有一天,需求变成这样:不是给书而是给一份报纸,让这位母亲讲一下报纸上的故事,报纸的代码如下:

class Newspaper{
	public String getContent(){
		return "林书豪38+7领导尼克斯击败湖人……";
	}
}

        这位母亲却办不到,因为她居然不会读报纸上的故事,这太荒唐了,只是将书换成报纸,居然必须要修改Mother才能读。假如以后需求换成杂志呢?换成网页呢?还要不断地修改Mother,这显然不是好的设计。原因就是Mother与Book之间的耦合性太高了,必须降低他们之间的耦合度才行。

我们引入一个抽象的接口IReader。读物,只要是带字的都属于读物:

interface IReader{
	public String getContent();
}

Mother类与接口IReader发生依赖关系,而Book和Newspaper都属于读物的范畴,他们各自都去实现IReader接口,这样就符合依赖倒置原则了,代码修改为:

class Newspaper implements IReader {
	public String getContent(){
		return "林书豪17+9助尼克斯击败老鹰……";
	}
}
class Book implements IReader{
	public String getContent(){
		return "很久很久以前有一个阿拉伯的故事……";
	}
}

class Mother{
	public void narrate(IReader reader){
		System.out.println("妈妈开始讲故事");
		System.out.println(reader.getContent());
	}
}

public class Client{
	public static void main(String[] args){
		Mother mother = new Mother();
		mother.narrate(new Book());
		mother.narrate(new Newspaper());
	}
}

运行结果:

妈妈开始讲故事
很久很久以前有一个阿拉伯的故事……
妈妈开始讲故事
林书豪17+9助尼克斯击败老鹰……

    这样修改后,无论以后怎样扩展Client类,都不需要再修改Mother类了。这只是一个简单的例子,实际情况中,代表高层模块的Mother类将负责完成主要的业务逻辑,一旦需要对它进行修改,引入错误的风险极大。所以遵循依赖倒置原则可以降低类之间的耦合性,提高系统的稳定性,降低修改程序造成的风险。

    采用依赖倒置原则给多人并行开发带来了极大的便利,比如上例中,原本Mother类与Book类直接耦合时,Mother类必须等Book类编码完成后才可以进行编码,因为Mother类依赖于Book类。修改后的程序则可以同时开工,互不影响,因为Mother与Book类一点关系也没有。参与协作开发的人越多、项目越庞大,采用依赖导致原则的意义就越重大。现在很流行的TDD开发模式就是依赖倒置原则最成功的应用。

         传递依赖关系有三种方式,以上的例子中使用的方法是接口传递,另外还有两种传递方式:构造方法传递setter方法传递,相信用过Spring框架的,对依赖的传递方式一定不会陌生。
在实际编程中,我们一般需要做到如下3点:

  • 低层模块尽量都要有抽象类或接口,或者两者都有。
  • 变量的声明类型尽量是抽象类或接口。
  • 使用继承时遵循里氏替换原则。

        依赖倒置原则的核心就是要我们面向接口编程,理解了面向接口编程,也就理解了依赖倒置。

本文转载自:http://blog.csdn.net/zhengzhb/article/details/7289269

zy643208
粉丝 2
博文 75
码字总数 9412
作品 0
成都
程序员
私信 提问
设计模式 2014-12-19

book: 阎宏《JAVA与模式》 架构设计栏目 http://blog.csdn.net/enterprise/column.html 概要: http://bbs.csdn.net/forums/Embeddeddriver 23种设计模式分别是: 1.单例模式 2.工厂方法模式...

jayronwang
2014/12/19
0
0
Java 23种设计模式 初步了解

总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接...

engeue
01/02
0
0
设计模式初步学习笔记(单例模式)

关于设计模式,很久以前通过在网上看了一些资料关于讲设计模式的(推荐大话设计模式),虽说都似乎看懂了,但每次在需要用到相关设计模式的时候总是想不起来,主要对每种设计模式使用场景没研...

lxsh_wyan
04/29
0
0
android与模式:设计原则

在谈设计模式之前,如果不谈设计原则,我认为是无根之浮萍。 为什么这么说,为什么我们要学设计模式,为什么前人将这些东西抽象和总结出来?这就是要了解设计原则的必要性,开始学的时候,可...

今幕明
2014/03/06
0
0
JavaScript设计模式总结

之前看过《JavaScript设计模式与开发实践》这本书,对书中的设计模式和一些相关案例也有了一定的了解,同时把这些设计模式的应用对应在在一些其他的项目中,进行了一些整理,如下仅供参考: ...

jefferyE
03/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

yii2做输入跳转到分页【未测试】

首先使用引用分页类 1、 1 use yii\data\Pagination; 2、控制器 1 //分页跳转 2 public function actionPagego(){ 3 $model = Knowledge::find(); 4 //原生sql语......

dragon_tech
12分钟前
0
0
实时计算轻松上手,阿里云DataWorks Stream Studio正式发布

Stream Studio是DataWorks旗下重磅推出的全新子产品。已于2019年4月18日正式对外开放使用。Stream Studi是一站式流计算开发平台,基于阿里巴巴实时计算引擎Flink构建,集可视化拖拽DAG和SQL...

阿里云官方博客
12分钟前
1
0
【阿里云新品发布·周刊】第9期:实时大数据开发难、运维难、应用难?来,一站解决!

点击订阅新品发布会! 新产品、新版本、新技术、新功能、价格调整,评论在下方,下期更新!关注更多内容,了解更多 最新发布 DataWorks Stream Studio重磅发布 2019年5月15日15时,阿里云Dat...

zhaowei121
17分钟前
0
0
常见的Web攻击手段——CSRF攻击

一、什么是CSRF攻击? 跨站请求伪造(Cross-Site Request Forgery, CSRF),恶意网站通过脚本向当前用户浏览器打开的其它页面的 URL 发起恶意请求,由于同一浏览器进程下 Cookie 可见性,导致用...

Lienson
17分钟前
0
0
H3C设备网络组建和设置

路由器: ER8300 交换机: S3600v2 说明:这次网络配置主要是模拟,这套网络是挂在办公室网络下的.由于办公室给我的网络是:192.168.3.0/24, 网关是:192.168.3.254. 所以我们规划如下: ER8300 wa...

WinkJie
18分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部