文档章节

装饰者模式

乒乓狂魔
 乒乓狂魔
发布于 2015/02/07 10:37
字数 776
阅读 136
收藏 1
点赞 2
评论 0
有时候为了传承某个类的一些功能,我们可以采用继承该类来获取功能,并可以通过覆写某些方法来进行功能加强。然而若想对一批类的功能进行加强,如果仍采用继承,不仅在代码上重复,并且不利于扩展。如下所示:
public interface Component {

	public void  fun();
}

public class ConcreteAComponent implements Component{

	@Override
	public void fun() {
		System.out.println("ConcreteAComponent");
	}

}

public class ConcreteBComponent implements Component{

	@Override
	public void fun() {
		System.out.println("ConcreteBComponent");
	}

}



接口Component有一个fun()方法,ConcreteAComponent、ConcreteBComponent都实现了该接口,完成了fun方法。现在的需求是,想对ConcreteAComponent、ConcreteBComponent所实现的fun方法进行加强,如想计算出fun方法所花费时间、想在fun方法执行前后输出一些信息等。

如果采用继承的话,加强ConcreteAComponent,则需要写一个类继承ConcreteAComponent,加强ConcreteBComponent,则需要写一个类继承ConcreteBComponent,就会造成每当要加强一个类时就必须要新建一个类继承它,在代码上造成严重的重复。
除了继承能够进行功能复用外,还有如下的复用方式:

public class ConcreteTimeDecorator implements Component{
	
	private Component component;

	public ConcreteTimeDecorator(Component component) {
		super();
		this.component = component;
	}

	@Override
	public void fun() {
		long start=System.currentTimeMillis();
		System.out.println("start at "+start);
		component.fun();
		long end=System.currentTimeMillis();
		System.out.println("end at "+end+",cost "+(end-start));
	}

}

ConcreteTimeDecorator 是一个时间计算装饰器,ConcreteTimeDecorator 实现了Component接口主要是为了替代要装饰的Component 对象。它内部保留了一个Component 的引用,对于那些ConcreteTimeDecorator 并不关心的方法,有具体的Component 对象来实现,而对于想要增强的方法加上自己的逻辑,由于ConcreteTimeDecorator 针对的是接口Component ,不依赖于任何一个具体的Component ,所以每当要增强一个具体的Component时,不用再添加新的类,和继承就不一样了,这样更加容易扩展。

再如下一个装饰着:

public class ConcretePrintDecorator implements Component{

	private Component component;

	public ConcretePrintDecorator(Component component) {
		super();
		this.component = component;
	}

	@Override
	public void fun() {
		System.out.println("before real component run");
		component.fun();
		System.out.println("after real component run");
	}

}

也是同样的道理。
我们使用装饰者模式:

ConcreteAComponent concreteAComponent=new ConcreteAComponent();
		
		ConcreteTimeDecorator concreteTimeDecorator=new ConcreteTimeDecorator(concreteAComponent);
		concreteTimeDecorator.fun();
		
		System.out.println("--------------------------------------------");
		ConcretePrintDecorator concretePrintDecorator=new ConcretePrintDecorator(concreteAComponent);
		concretePrintDecorator.fun();

运行效果如下:
start at 1416349131419
ConcreteAComponent
end at 1416349131419,cost 0
--------------------------------------------
before real component run
ConcreteAComponent
after real component run

可见ConcreteTimeDecorator 、ConcretePrintDecorator 对ConcreteAComponent 进行装饰后,加强了对应的功能,同样他们可以对ConcreteBComponent进行装饰加强ConcreteBComponent的功能。整个类图就如下:
 

这里稍加改动了一些,把ConcreteTimeDecorator和ConcretePrintDecorator的一些共性部分拿出来,作为基类。

这就是装饰者模式,jdk中装饰者模式也很常见,如常用的BufferedInputStream,它就是对InputStream加入了缓冲功能来提高性能,如下所示:



其中FilterInputStream就是一个装饰者的基类,它把所有装饰者共性的部分拿出来,即持有一个InputStream引用,如下:
public
class FilterInputStream extends InputStream {
   
    protected volatile InputStream in;

    protected FilterInputStream(InputStream in) {
        this.in = in;
    }
   //略
}

这种形式和刚才上面的形式基本一样,然后BufferedInputStream再继承FilterInputStream 。

若想转载请注明出处:   http://lgbolgger.iteye.com/blog/2154368
作者:iteye的乒乓狂魔

© 著作权归作者所有

共有 人打赏支持
乒乓狂魔
粉丝 979
博文 105
码字总数 271356
作品 0
长宁
程序员
设计模式——装饰者模式:婚纱照收费的简单实现

装饰者模式 在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。 装饰者模式特点 装饰者和被装饰对象有相同的超类型...

OSC一霸
2016/10/20
3K
12
Decorator 装饰者模式

动机 我们可以通过继承来静态地(在编译期间)扩展对象的功能,不过有时我们也需要在使用对象的时候动态地(在运行时)扩展它 。 我来看一个经典的例子,图形窗口。比如说我们要扩展这个图形...

holysu
2017/11/26
0
0
Head First Design Pattern 读书笔记(3)装饰者模式

Head First Design Pattern 读书笔记(3) Decorator Pattern 装饰者模式 Decorator Pattern 类图 ![装饰者模式类图][2] 定义 装饰者模式:通过让组件类与装饰者类实现相同的接口,装饰类可以...

Tek_Eternal
2015/01/03
0
0
Pattern-No.05 设计模式之装饰者模式

1、装饰者模式定义:动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为。 2、要点 具体被...

蓝汀华韶
2015/04/03
0
0
设计模式之装饰者模式(Decorator Pattern)

模式分析: 动态地给一个对象添加一些额外的职责。就增加功能来说, Decorator模式相比生成子类更为灵活。该模式以对客 户端透明的方式扩展对象的功能。 使用情景: 在不影响其他对象的情况下...

bug_404
01/18
0
0
javascript设计模式-------装饰者模式

一、概念 装饰者提供比继承更有弹性的替代方案。 装饰者用于包装同接口的对象,不仅允许你向方法添加行为,而且还可以将方法设置成原始对象调用(例如装饰者的构造函数)。 装饰者通过重载方...

漂泊者及其影子
2014/01/13
0
0
Java设计模式之-装饰者模式(Decorator)

说到装饰,我们首先能想到的是房间中的各种陈设和布景。在房间中,每增加一个装饰物品,整个房间的氛围都会有所改变。而我们的装饰者模式也起到了这么一个作用: Attach additional responsi...

Mock2052
2017/12/13
0
0
Head first设计模式(3)

装饰者模式 1、我曾经以为男子汉应该用继承处理一切,后来我领教到运行时扩展,远比编译时期的继承威力大,看看我现在光彩的样子 2、“给爱用继承的人一个全新的设计眼界”,我们即将再度讨论...

祥林会跟你远走高飞
2014/12/31
0
0
6. 装饰者模式

设计模式并非是难以理解, 或是难以应用到实践中的, 相反的, 设计模式恰恰代表了某些场景下的最佳实践! 这些设计模式通常被有经验的开发者们所采用。 设计模式是开发者们在开发过程中面临的一...

mtshen
01/10
0
0
装饰者模式

《Head First 设计模式》-- 装饰者模式 首先看一个例子: 以装饰者构造饮料订单 有个饮料的基类: 以开始 继承于 类,有一个用来计算饮料价钱的方法 现在顾客想要摩卡,所以建立一个对象,并用...

tsmyk0715
2017/10/15
11
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

rabbitmq学习记录(三)

工作队列:一个生产者,多个消费者,生产者直接将消息发送到rabbitmq的队列之中 默认采用的是轮询分配:即不管消费者处理信息的效率,队列给所有消费者轮流发送一条信息,直至消息发送完毕 ...

人觉非常君
22分钟前
0
0
Java 之 反射

反射,剖析 Java类 中的 各个组成部分,映射成 一个个 Java对象,多用于 框架和组件,写出复用性高的通用程序。 测试类代码如下: class Person { private String name; public St...

绝世武神
26分钟前
0
0
华为nova3超级慢动作酷玩抖音,没有办法我就是这么强大

华为nova3超级慢动作酷玩抖音,没有办法我就是这么强大!华为nova3超级慢动作酷玩抖音,没有办法我就是这么强大! 在华为最新发布的nova 3手机上,抖音通过华为himedia SDK集成了60fps、超级...

华为终端开放实验室
32分钟前
0
0
多 SSH Key 实现同一台服务器部署多 Git 仓库

本文以以下需求为背景,介绍详细的做法: 需在同一台服务器同时部署两个不同的 Github 仓库(对 Bitbucket 等 git 服务同样适用) root 用户可在远程登录 SSH 后附上预期的 SSH Key 进行 gi...

yeahlife
34分钟前
0
0
003. es6数值的扩展

一、普通扩展 Number 方法,将字符串、数值转为十进制 : Number('0b111') Number.isFinite() 用来检查一个数值是否为有限的:Number.isFinite(15) Number.isNan() 用来检查一个值是否为NaN N...

秋季长青
48分钟前
0
0
C语言数组和指针的语法糖

对于C语言,我可以这样秀:比如当创建一个数组arr[n]之后,一般我们去遍历数组的时候是for (int i = 0; i < n; i++) { a[i]; }但是我知道下表访问符[]是个语法糖,也就是说a[i]在编译器看来是...

ustbgaofan
56分钟前
0
0
Call to undefined function bcmath()的解决方法

乐意黎的ECS主机环境,Centos7.2 + PHP7 由于使用了bcdiv()函数,运行时总在抛错。 Fatal error: Call to undefined function bcmath() in /usr/loca/apache/htdocs/... on line 4 一查得知:......

dragon_tech
今天
0
0
css优先级

..

architect刘源源
今天
0
0
【转】Twitter的分布式自增ID算法snowflake

结构 snowflake的结构如下(每部分用-分开): 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 第一位为未使用,接下来的41位为毫秒级时间(41位的长度可以...

talen
今天
0
0
hive支持行级修改

Hive从0.14版本开始支持事务和行级更新,但缺省是不支持的,需要一些附加的配置。要想支持行级insert、update、delete,需要配置Hive支持事务。 一、Hive具有ACID语义事务的使用场景 1. 流式...

hblt-j
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部