装饰器模式——给类美个颜

993 阅读3分钟

「这是我参与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? ......

总结

点个赞吧