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

相关推荐
烂蜻蜓4 小时前
Flask入门教程(十二):表单处理——从基础到Flask-WTF完整实践
后端·python·flask
2601_9620559711 小时前
跟据spring boot版本,查看对应的tomcat,并查看可支持的tomcat的版本范围
spring boot·后端·tomcat
Lost of 程序猿12 小时前
ASP.NET Core API 幂等性设计深度实战:从一次重复申领事故说起
后端·asp.net
QQ_216962909613 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
郑州光合科技余经理15 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
IT_陈寒15 小时前
Vue的嵌套组件竟然吃掉了我的事件?
前端·人工智能·后端
workflower15 小时前
人形机器人灵巧手产业链
人工智能·设计模式·机器人·云计算·无人机
大辉狼_音频架构16 小时前
进阶:从源码编译 SOF 固件与 topology
后端
大辉狼_音频架构16 小时前
上板:让 SOF 在 FRDM-i.MX8MP 上跑起来
后端
大辉狼_音频架构16 小时前
FRDM-IMX8MP UUU 烧录 eMMC 指南
后端