「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」
哈喽,大家好,我是一条~
设计模式,虽迟但到。
对设计模式不是很熟悉的同学可以先看一下《23种设计模式的一句话通俗解读》全面的了解一下设计模式,形成一个整体的框架,再逐个击破。
往期回顾:设计模式合集
今天我们一块看一下装饰器模式,是结构型设计模式。
定义
官方定义
向一个现有的对象添加新的功能,同时又不改变其结构。
通俗解读
你有很多活要干,如果你全部派给下属,那你要管理的下属会越来越多,这是你可以招一个助手(装饰器)来增强你,让助手再去把活派给下属,你只需要管理助手就行了。
结构图
抽象构件:定义一个抽象接口以规范准备接收附加责任的对象。
被装饰类:通过装饰角色为其添加一些职责。
抽象装饰类:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
具体装饰类:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
代码演示
目录结构
建议跟着一条学设计模式的小伙伴都建一个maven
工程,并安装lombok
依赖和插件。
并建立如下包目录,便于归纳整理。
pom
如下
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
开发场景
直播相信大家再熟悉不过,
代码实现
新建直播接口
public interface Live {
public void startLive();
}
开直播
public class MyLive implements Live{
@Override
public void startLive() {
System.out.println("My开始直播");
}
}
刚开始直播,都是原生态,没有美颜,没有声卡,也就没人看,所以需要装饰一下直播类。
新建装饰类接口,实现被装饰类
public interface LiveDecorator extends Live{
// 增强接口
void enable();
}
新建美颜装饰器
public class LiveFaceDecorator implements LiveDecorator{
private final Live live;
public LiveFaceDecorator(Live live) {
this.live = live;
}
public void enable(){
System.out.println("开启美颜");
}
// 实现被装饰类的原有功能,并增强
@Override
public void startLive() {
live.startLive();
enable();
}
}
新建声卡装饰器
public class LiveVoiceDecorator implements LiveDecorator{
private final Live live;
public LiveVoiceDecorator(Live live) {
this.live = live;
}
@Override
public void enable(){
System.out.println("开启声卡");
}
@Override
public void startLive() {
live.startLive();
enable();
}
}
测试类
/**
* 装饰器模式测试类
*/
public class MainTest {
public static void main(String[] args) {
// 创建直播
MyLive myLive = new MyLive();
myLive.startLive();
System.out.println("增强直播类---------");
// 开启美颜功能
LiveFaceDecorator faceDecorator = new LiveFaceDecorator(myLive);
faceDecorator.startLive();
// 开启声卡
LiveVoiceDecorator voiceDecorator = new LiveVoiceDecorator(myLive);
voiceDecorator.startLive();
}
}
输出结果
应用场景
装饰器的价值在于装饰,他并不影响被装饰类本身的核心功能。
在一个继承的体系中,子类通常是互斥的。比如一辆车,品牌只能要么是奥迪、要么是宝马,不可能同时属于奥迪和宝马,而品牌也是一辆车本身的重要属性特征。
但当你想要给汽车喷漆,换坐垫,或者更换音响时,这些功能是互相可能兼容的,并且他们的存在不会影响车的核心属性:那就是他是一辆什么车。这时你就可以定义一个装饰器:喷漆。不管他装饰的车是宝马还是奥迪,喷漆效果都可以实现。
什么场景使用? SpringSession中如何进行session与redis关联?HttpRequestWrapper MyBatisPlus提取了QueryWrapper,这是什么? Spring中的BeanWrapper是做什么? Spring Webflux中的 WebHandlerDecorator? ......
总结
点个赞吧