三分钟理解“装饰模式”——设计模式轻松掌握

什么是装饰模式?

在运行的过程中,给一个对象动态地添加一些额外的行为。每一个具体的装饰类都为被装饰类添加一个功能。

装饰模式的类图

1.需要被装饰的对象所在的类和装饰类都有一个共同的父类Component,该类中拥有需要添加额外功能的函数:operation();

class ConcreteComponent() extends Component{
	public void operation(){
		//本函数原本就要做的事情
	}
}

2.ConcreteComponent是需要被装饰的类;Decorator是装饰类。

3.Decorator类中持有被装饰对象的引用,客户端通过setComponent(Component)设置;

4.Decorator类的operation()函数中,执行了被用户set进去的component对象中的operation()函数,也就是首先执行被装饰类原本的功能;

class Decorator() extends Component{//需要被装饰的对象private Component component;//提供给客户端将需要被装饰的对象设置进来public void setComponent(Component component){this.component = component;}//执行需要被装饰对象原本的operation函数public void operation(){this.component.operation();}}

Decorator的子类们的operation()函数,拥有被装饰类原本的功能和新需要增加的功能。

class ConcreteDecorator() extends Decorator{
	//需要被装饰的对象
	private Component component;

	//提供给客户端将需要被装饰的对象设置进来
	public void setComponent(Component component){
		this.component = component;
	}

	//执行需要被装饰对象原本的operation函数+附加的功能
	public void operation(){
		//新的功能……………………
		super.operation();
		//新的功能……………………
	}
}

客户端代码:

public static void main(String[] args) {
	//创建一个需要被装饰的对象
	ConcreteComponent concreteComponent = new ConcreteComponent();

	//创建一系列修饰类的对象
	Decorator decoratorA = new ConcreteDecoratorA();
	Decorator decoratorB = new ConcreteDecoratorB();

	//先使用ConcreteDecoratorA包装被装饰对象
	decoratorA.setComponent(concreteComponent);
	//再使用ConcreteDecoratorB包装decoratorA对象
	decoratorB.setComponent(decoratorA);
}

此时,decoratorB对象就是原本需要被装饰的concreteComponent对象,只不过这个对象的operation()函数在原本operation()的基础上增加了ConcreteDecoratorA和ConcreteDecoratorB新的功能。

装饰模式和建造者模式的异同?

相同点:建造者模式和装饰模式都使用了面向切面编程的思想,装饰模式中的装饰类和建造者模式中建造者类的一个个函数都是为被装饰对象附加函数额外功能或为对象中的属性赋值。

不同点:建造者给对象添砖加瓦的顺序是固定的,在Director类中写好的;

而装饰模式中需要添加哪些操作是由客户端决定的。

建造者模式的详细介绍请移步至:http://blog.csdn.net/u010425776/article/details/48104143

装饰模式的优点

装饰模式是为已有的功能动态添加更多功能的一种方式。

以往在设计程序的过程中,当系统需要新功能时,就在旧的类中添加新的代码。

但这种方式的问题在于,如果它们在类中添加了新的方法、新的字段、新的逻辑,就会增加主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才回执行的特殊行为的需要。

而装饰模式提供了一种非常好的解决方案,

它把每一个要额外添加的功能单独封装在一个个类中,并让这个类包装它所要装饰的对象。

因此,当一个类需要执行特殊行为时,客户端就可以在运行时有选择地添加所需要的附加功能。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏圣杰的专栏

Asp.net mvc 知多少(五)

本系列主要翻译自《ASP.NET MVC Interview Questions and Answers 》- By Shailendra Chauhan,想...

3516
来自专栏JAVA高级架构

JAVA后端面试100 Q&A之第一篇

731
来自专栏wOw的Android小站

[设计模式]之十二:状态模式

在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的(stateful)对象,这样的对象状态是从事先定义好的一...

361
来自专栏偏前端工程师的驿站

线程间通讯:WaitHandler使用实例及分析

实例效果: ? 1.点击“启动线程”会启动一个线程t每隔2秒在listbox上插入一条新记录。 2.点击“关闭线程”会停止线程t,但不是马上停止而是等待线程t当...

1645
来自专栏java初学

unix网络编程——I/O多路复用之epoll

  当程序进行IO时,如果数据尚未准备好,那么IO将处于阻塞状态。当某个进程有多个打开的文件,比如socket,那么其后的所有准备好读写的文件将受到阻塞的影响而...

462
来自专栏大眼瞪小眼

Java线程:概念与使用

Java线程大总结 原文章地址:一篇很老的专栏,但是现在看起来也感觉深受启发,知识点很多,很多线程特点我没有看,尴尬。但是还是整理了一下排版,转载一下。

512
来自专栏龙首琴剑庐

Java多线程并发编程一览笔录

知识体系图: ? 1、线程是什么? 线程是进程中独立运行的子任务。 2、创建线程的方式 方式一:将类声明为 Thread 的子类。该子类应重写 Thread 类...

34410
来自专栏JMCui

多线程编程学习三(线程间通信).

一、概要 线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线程间的通信就是成为整体的必用方案之一。可以说,使线程进行通信后,系统...

2574
来自专栏Spark学习技巧

java线程池模型

一, 线程池与普通线程 1 普通线程 Java实现多线程,常见的有以下三种方式: 1 继承Thread,重写该类的run()方法 2 实现Runnable 实现...

1747
来自专栏微信公众号:Java团长

Java多线程并发编程一览笔录

方式一:将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法

632

扫描关注云+社区