文档章节

装饰者模式  

二龙湖小峰哥
 二龙湖小峰哥
发布于 2014/12/04 17:09
字数 1185
阅读 18
收藏 0

God bless you

 

装饰者模式

Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案。

 

意图:

动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

 

设计原则:

1. 多用组合,少用继承。

利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。

2. 类应设计的对扩展开放,对修改关闭。

 

要点:

1. 装饰者和被装饰对象有相同的超类型。

2. 可以用一个或多个装饰者包装一个对象。

3. 装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。

4. 对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。

5. 装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为。

6. 装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。在实际项目中可以根据需要为装饰者添加新的行为,做到“半透明”装饰者。

7. 适配器模式的用意是改变对象的接口而不一定改变对象的性能,而装饰模式的用意是保持接口并增加对象的职责。

 

实现:

clip_image002

Component:

定义一个对象接口,可以给这些对象动态地添加职责。

  Component
{	 operation();
}

 

Concrete Component:

定义一个对象,可以给这个对象添加一些职责。

  ConcreteComponent  Component
{	  operation()
	{		
	}
}

 

Decorator:

维持一个指向Component对象的引用,并定义一个与 Component接口一致的接口。

  Decorator  Component
{	 Decorator(Component component)
	{		.component = component;
	}	
	  operation()
	{
		component.operation();
	}	
	 Component component;
}

 

Concrete Decorator:

在Concrete Component的行为之前或之后,加上自己的行为,以“贴上”附加的职责。

  ConcreteDecorator  Decorator
{	  operation()
	{		
		
		.operation();
		
		addBehavior();
	}	
	  addBehavior()
	{		
	}
}

 

模式的简化:

1. 如果只有一个Concrete Component类而没有抽象的Component接口时,可以让Decorator继承Concrete Component。

clip_image004

2. 如果只有一个Concrete Decorator类时,可以将Decorator和Concrete Decorator合并。

clip_image006

 

适用性:

以下情况使用Decorator模式

1. 需要扩展一个类的功能,或给一个类添加附加职责。

2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。

3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

 

优点:

1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。

2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。

2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

 

装饰模式在Java I/O库中的应用:

clip_image008

编写一个装饰者把所有的输入流内的大写字符转化成小写字符:

 java.io.FilterInputStream; java.io.IOException; java.io.InputStream;  LowerCaseInputStream  FilterInputStream
{	 LowerCaseInputStream(InputStream in)
	{		(in);
	}
	
	@Override	  read()  IOException
	{		 c = .read();		 (c == -1 ? c : Character.toLowerCase(() c));
	}
	
	@Override	  read([] b,  offset,  len)  IOException
	{		 result = .read(b, offset, len);		
		 ( i = offset; i < offset + result; i++)
		{
			b[i] = () Character.toLowerCase(() b[i]);
		}		
		 result;
		
	}
}

 

测试我们的装饰者类:

 java.io.*;  InputTest
{	   main(String[] args)  IOException
	{		 c;		
		
		{
			InputStream in =  LowerCaseInputStream( BufferedInputStream(					 FileInputStream("")));			
			 ((c = in.read()) >= 0)
			{
				System.out.print(() c);
			}
			
			in.close();
		}		 (IOException e)
		{
			e.printStackTrace();
		}
	}
}

© 著作权归作者所有

共有 人打赏支持
上一篇: hashcode
下一篇: 类找不到总结
二龙湖小峰哥
粉丝 3
博文 13
码字总数 13985
作品 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
装饰者模式 && ES7 decorator装饰器

装饰者模式 在提及这个新特性前我们先了解一下设计模式中的装饰者模式。 定义 装饰者模式能够在不改变对象自身的基础上,在程序运行期间给对像动态的添加职责。与继承相比,装饰者是一种更轻...

Eason_Wong
2018/09/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

富兰克林的人生信条

春节假期期间读了富兰克林自传,这位饱经风霜的老人出身贫寒,只读过两年书,但是通过刻苦自学和不懈奋斗还是取得了令人难以置信的成就,他的一生可以作为我们普通人的励志典范。 富兰克林 ...

春哥大魔王的博客
今天
1
0
不用中间变量交换 a ,b(三种方法)

1、加减法:该方法可以交换整型和浮点型数值的变量,但在处理浮点型的时候有可能出现精度的损失。 a = a + b; b = a - b; a = a - b; 2、异或法:可以完成对整型变量的交换,对于浮点型变量它...

robslove
今天
5
0
一文了解 OutOfMemory 及解决方案

1. Java 堆空间 发生频率 5颗星 造成原因 无法在 Java 堆中分配对象 吞吐量增加 应用程序无意中保存了对象引用,对象无法被 GC 回收 应用程序过度使用 finalizer。finalizer 对象不能被 GC 立...

java菜分享
今天
6
0
高效遍历Java容器

通过本文,你可以更深入的学习 Java 语言中 forEach 语法的知识,以及它和 C 语言形式的 for 循环、 Steam API 的对比。 简介 Java 程序员经常使用容器,比如 ArrayList 和 HashSet。Java 8 ...

微笑向暖wx
今天
7
0
SpringBoot整合Swagger测试api构建

什么是Swagger? Swagger是什么:THE WORLD’S MOST POPULAR API TOOLING 根据官网的介绍: Swagger Inspector:测试API和生成OpenAPI的开发工具。Swagger Inspector的建立是为了解决开发者的...

编程SHA
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部