设计模式-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 类似对象的外壳,通过一层层的嵌套,动态地给对象添加功能。

相关推荐
Loo国昌30 分钟前
【LangChain1.0】第八阶段:文档处理工程(LangChain篇)
人工智能·后端·算法·语言模型·架构·langchain
vx_bisheyuange35 分钟前
基于SpringBoot的海鲜市场系统
java·spring boot·后端·毕业设计
李慕婉学姐1 小时前
【开题答辩过程】以《基于Spring Boot和大数据的医院挂号系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
大数据·spring boot·后端
源代码•宸2 小时前
Leetcode—3. 无重复字符的最长子串【中等】
经验分享·后端·算法·leetcode·面试·golang·string
0和1的舞者3 小时前
基于Spring的论坛系统-前置知识
java·后端·spring·系统·开发·知识
Yu_Lijing3 小时前
基于C++的《Head First设计模式》笔记——状态模式
c++·笔记·设计模式
invicinble3 小时前
对于springboot
java·spring boot·后端
Engineer邓祥浩4 小时前
设计模式学习(18) 23-16 迭代器模式
学习·设计模式·迭代器模式
码界奇点4 小时前
基于Spring Boot与Vue的校园后台管理系统设计与实现
vue.js·spring boot·后端·毕业设计·源代码管理
爱编程的小庄4 小时前
Rust 发行版本及工具介绍
开发语言·后端·rust