设计模式-Decorator

组成

结构型模式涉及到如何组合类和对象,以获得更大的结构,更丰富的功能。主要有"类继承、对象组合"两种方式,

装饰器模式(Decorator)可以动态地给对象添加一些额外的功能,比如有时我们希望给某个对象而不是整个类添加一些功能,那么就可以用装饰器模式,把目标对象嵌入到装饰器对象中。

装饰器模式的组成如下:

Component:一个接口对象

ConcreteComponent:Component 的具体实现类

Decorator:装饰器接口,维持一个指向 Component 对象的引用,必须继承自 Component 接口

ConcreteDecorator:装饰器的具体实现类,用于向 Component 对象添加职责

Decorator 将请求转发给它的 Component 对象,并有可能在转发请求前后执行一些附加的动作。

应用场景

1、希望给某个对象增加功能,而不是整个类,不会影响这个类其他对象。

2、继承不利于系统维护,甚至不能使用继承关系的场景。

3、需要动态、透明的给对象添加或撤销功能。

示例代码

Java 类库中 Collections 就有一个很典型的装饰器模式实现:Collecitons.SynchronizedList()。

java 复制代码
List<String> list = Collections.synchronizedList(new ArrayList<>());

该方法可以把非线程安全的 List 对象包装成线程安全的 List 对象返回,很符合"给某个对象增加功能,但不影响整个类"的要求。

改方法的内部实现,是使用一个新的类 SynchronizedList作为装饰器,包装了传入的 List 对象,该类的定义如下:

java 复制代码
static class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> {
	private static final long serialVersionUID = -7754090372962971524L;

	final List<E> list;

	SynchronizedList(List<E> list) {
		super(list);
		this.list = list;
	}
	SynchronizedList(List<E> list, Object mutex) {
		super(list, mutex);
		this.list = list;
	}

	
	public E get(int index) {
		synchronized (mutex) {return list.get(index);}
	}
}

可以看到,这个装饰器类自身也继承了它要装饰的 Component (List 接口),并实现了 List 的方法,在调用时,会使用 synchroinzed 加锁,在转发给被装饰的对象 list,让 list 的方法变得线程安全。

优点和缺点

优点

1、比继承更加灵活

使用装饰器可以在需要的时候给某个对象增加功能,而不是使用继承,让所有子类对象都被增强。

2、简单、即用即付

不需要在一个装饰器类中定义所有需要增强的功能,而是可以定义多个简单的装饰器类,逐个调用,逐渐给 component 添加功能,从简单的部件组合出复杂的功能。

缺点

1、Decorator 和 Compnent 不一样

虽然 Decorator 继承了 Compnent 接口,但实际上同名方法和 Compnent 还是有差异的,不能把 Decorator 当做 Compnent 使用。

2、会产生很多装饰器类

如果要添加的功能很多,会创建很多相似的装饰器类和对象,使的维护和排查更加困难。

小结

装饰器模式可以在不改变 Compnent 实现的前提下,给 Compnent 对象增加功能,并且可以保持 Compnent 的简单性。

Decorator 类似对象的外壳,通过一层层的嵌套,动态地给对象添加功能。

相关推荐
码上一元2 小时前
SpringBoot自动装配原理解析
java·spring boot·后端
枫叶_v4 小时前
【SpringBoot】22 Txt、Csv文件的读取和写入
java·spring boot·后端
杜杜的man5 小时前
【go从零单排】Closing Channels通道关闭、Range over Channels
开发语言·后端·golang
java小吕布5 小时前
Java中Properties的使用详解
java·开发语言·后端
2401_857610036 小时前
Spring Boot框架:电商系统的技术优势
java·spring boot·后端
杨哥带你写代码8 小时前
网上商城系统:Spring Boot框架的实现
java·spring boot·后端
camellias_8 小时前
SpringBoot(二十一)SpringBoot自定义CURL请求类
java·spring boot·后端
背水9 小时前
初识Spring
java·后端·spring
晴天飛 雪9 小时前
Spring Boot MySQL 分库分表
spring boot·后端·mysql
weixin_537590459 小时前
《Spring boot从入门到实战》第七章习题答案
数据库·spring boot·后端