别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!(1)

简介: 别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!(1)

背景

你还在写满屏的爆炸类吗?


就是不管三七二十一,把所有代码写在一个类里面,这样代码不优雅不说,如果改动涉及到老代码,可能还会影响线上的系统稳定性。


其实,很多情况,我们巧妙地利用设计模式就能解决很多潜在的系统问题,今天栈长就教大家使用装饰器模式,在不改动老代码的前提下扩展功能,不但能提升代码优雅性,还能不影响现有的功能,谁用谁知道,真香!!


什么是装饰器模式?

装饰器模式,从字面上理解,顾名思义,就是一种装饰模式,它可以在不改动原有代码的情况下,对现有的对象、行为进行新的层次的包装、装饰,增强原有的基本功能以提供更丰富的能力。


举个简单的装修的小例子:

清理 > 刮腻子 > 涂油漆 > 挂壁画


也可以是:

清理 > 刮腻子 > 贴大理石 > 挂电视


或者可以是:

清理 > 刮腻子 > 贴墙纸


这是一步步的简单装修墙面过程(哈哈,大概如此,我不是专业的),这就是装饰器模式,装饰的每个步骤互不干涉,但后面的步骤需要依赖前一个步骤的完成,后面的步骤可以不断在前一个的装饰基础上进行增加。


装饰器模式结构图如下:

image.png


装饰器模式类结构如下:


Component:组件接口类,定义被装饰类的基本功能


ConcreteComponent:组件接口的基本实现类


Decorator:装饰器角色类, 实现并持有一个 Component 对象实例


ConcreteDecorator:装饰器的实现类


装饰器模式的优点:


1、不改动原有代码,动态增加功能;


2、对象之间不会相互依赖,松耦合,够优雅;


3、符合开闭原则,扩展性好、便于维护;


装饰器模式的缺点:


1、装饰环节如果很多的话,会造成装饰器类膨胀;


2、装饰器层层嵌套比较复杂,使用者必须清楚所有的装饰器类及其用途;


装饰器模式实战

我们把上面的装修的案例用装饰器模式实现一下。


组件接口类:

/**
 * 墙面装修接口
 * @author: 栈长
 * @from: 公众号Java技术栈
 */
public interface WallBeautify {
    /**
     * 装修操作
     * @author: 栈长
     * @from: 公众号Java技术栈
     */
    void operation();
}

组件接口的基本实现类:

/**
 * 墙面装修基本实现(清理墙面)
 * @author: 栈长
 * @from: 公众号Java技术栈
 */
public class WallBeautifyClean implements WallBeautify {
    @Override
    public void operation() {
        System.out.println("开始清理墙面");
    }
}


装饰器角色类:

这是一个抽象类,实现并持有一个 Component 对象实例,这里使用的是聚合,而不是继承,这也是装饰器模式的要点所在。

/**
 * 墙面装修装饰器角色
 * @author: 栈长
 * @from: 公众号Java技术栈
 */
public abstract class WallBeautifyDecorator implements WallBeautify {
    /**
     * 持有一个 Component 对象实例
     * @author: 栈长
     * @from: 公众号Java技术栈
     */
    private WallBeautify wallBeautify;
    public WallBeautifyDecorator(WallBeautify wallBeautify) {
        this.wallBeautify = wallBeautify;
    }
    @Override
    public void operation() {
        wallBeautify.operation();
        decoration();
    }
    /**
     * 装饰器实现类自定义实现方法
     * @author: 栈长
     * @from: 公众号Java技术栈
     */
    public abstract void decoration();
}

覆写原操作方法,在原操作之后再进行装饰,所以需要提供一个抽象的 decoration 方法供不同的装饰器的实现类去实现。


装饰器的实现类:

这里定义了 3 个装修过程:

刮腻子 > 涂油漆 > 挂壁画

所以各自去继承 装饰器角色类 并实现其装饰方法:

/**
 * 墙面装修装饰器角色实现(刮腻子)
 * @author: 栈长
 * @from: 公众号Java技术栈
 */
public class WallBeautifyPutty extends WallBeautifyDecorator {
    public WallBeautifyPutty(WallBeautify wallBeautify) {
        super(wallBeautify);
    }
    @Override
    public void decoration() {
        System.out.println("开始刮腻子");
    }
}
/**
 * 墙面装修装饰器角色实现(涂油漆)
 * @author: 栈长
 * @from: 公众号Java技术栈
 */
public class WallBeautifyPaint extends WallBeautifyDecorator {
    public WallBeautifyPaint(WallBeautify wallBeautify) {
        super(wallBeautify);
    }
    @Override
    public void decoration() {
        System.out.println("开始涂油漆");
    }
}
/**
 * 墙面装修装饰器角色实现(挂壁画)
 * @author: 栈长
 * @from: 公众号Java技术栈
 */
public class WallBeautifyHang extends WallBeautifyDecorator {
    public WallBeautifyHang(WallBeautify wallBeautify) {
        super(wallBeautify);
    }
    @Override
    public void decoration() {
        System.out.println("开始挂壁画");
    }
}

测试一下:

/**
 * 装饰器模式测试类
 * @author: 栈长
 * @from: 公众号Java技术栈
 */
public class DecoratorTest {
    public static void main(String[] args) {
        // 清理墙面
        WallBeautify wallBeautifyClean = new WallBeautifyClean();
        wallBeautifyClean.operation();
        System.out.println("--------------");
        // 刮腻子
        WallBeautify wallBeautifyPutty = new WallBeautifyPutty(wallBeautifyClean);
        wallBeautifyPutty.operation();
        System.out.println("--------------");
        // 涂油漆
        WallBeautify wallBeautifyPaint = new WallBeautifyPaint(wallBeautifyPutty);
        wallBeautifyPaint.operation();
        System.out.println("--------------");
        // 挂壁画
        WallBeautify wallBeautifyHang = new WallBeautifyHang(wallBeautifyPaint);
        wallBeautifyHang.operation();
        System.out.println("--------------");
        // 多层嵌套
        WallBeautify wbh = new WallBeautifyHang(new WallBeautifyPaint(
                new WallBeautifyPutty(new WallBeautifyClean())));
        wbh.operation();
        System.out.println("--------------");
    }
}

本节教程所有实战源码已上传到这个仓库:

https://github.com/javastacks/javastack

输出结果:

开始清理墙面
--------------
开始清理墙面
开始刮腻子
--------------
开始清理墙面
开始刮腻子
开始涂油漆
--------------
开始清理墙面
开始刮腻子
开始涂油漆
开始挂壁画
--------------
开始清理墙面
开始刮腻子
开始涂油漆
开始挂壁画
--------------

结果输出正常!

可以看到,装饰器模式的使用还是相对比较简单的,使用装饰器模式可以达到不同的装饰效果,这样即满足了不同客户的需求,而又不用改动原有的代码,还是挺香的。

相关文章
|
6月前
|
存储 缓存 弹性计算
2026年阿里云 c7 实例(ecs.c7.2xlarge)配置与性能测评
阿里云c7实例(ecs.c7.2xlarge)的8核16G配置,搭配1M - 5M可选带宽和40GB ESSD云盘,是专门为企业级计算密集型场景设计的高性能云服务器选择。该实例依托第三代神龙云服务器架构,搭载了Intel Xeon可扩展处理器,核心亮点在于算力强劲、运行稳定,还具备企业级安全保障,对于高并发交易、批量计算这类对CPU性能要求苛刻的业务,适配性极高。下面从价格、性能、适用场景和选购要点四个方面,为大家通俗解读。
455 10
|
6月前
|
Linux 虚拟化 iOS开发
UTM 5.0.0 发布 - 基于 QEMU 的 macOS 虚拟机与模拟器应用
UTM 5.0.0 发布 - 基于 QEMU 的 macOS 虚拟机与模拟器应用
816 0
UTM 5.0.0 发布 - 基于 QEMU 的 macOS 虚拟机与模拟器应用
|
10月前
|
机器学习/深度学习 算法 BI
汽车雷达系统的干扰缓解:现状调查与未来趋势——论文阅读
本文系统综述了汽车雷达干扰缓解技术的最新进展,提出基于物理域避免、主动避免、反应式信号重建和被动调制技术的四类划分方法,深入分析各类策略的原理、优劣及实施挑战,并强调跨学科合作与监管协同对未来发展的关键作用。
676 4
汽车雷达系统的干扰缓解:现状调查与未来趋势——论文阅读
|
机器学习/深度学习 缓存
Block Transformer:通过全局到局部的语言建模加速LLM推理
Block Transformer是一种优化自回归语言模型推理效率的新架构,通过块级自注意力来平衡全局和局部依赖,提高吞吐量。模型包含嵌入器、块解码器和令牌解码器,其中块解码器处理全局依赖,令牌解码器处理局部细节。这种方法减轻了KV缓存的延迟和内存开销,尤其是在长序列处理中。实验显示,尽管Block Transformer参数量增加,但推理速度显著提升,尤其是在大块长度和优化的组件比例下,实现了性能与速度的平衡。
886 7
|
11月前
|
人工智能 数据可视化 决策智能
京东零售重磅开源 | OxyGent:像搭乐高一样组装AI团队,实现群体智能
京东零售Oxygen团队正式开源发布多智能体协作框架——OxyGent。这一创新框架致力于帮助开发者高效组装多智能体协作系统,实现智能体间的无缝协作、弹性扩展与全链路可追溯。推动人工智能从“单点突破”迈向“群体智能”时代。
788 0
|
存储 运维 监控
百万指标,秒级查询,零宕机——时序数据库 TDengine 在 AIOps 中的硬核实战
本篇文章详细讲述了七云团队在运维平台中如何利用 TDengine 解决海量时序数据存储与查询的实际业务需求。内容涵盖了从数据库选型、方案落地到业务挑战及解决办法的完整过程,特别是分享了升级 TDengine 3.x 时的实战经验,给到有需要的小伙伴参考阅读。
778 1
|
数据采集 人工智能 供应链
《AI赋能工业制造:开启智能生产新时代》
在新一轮科技革命中,人工智能(AI)与工业制造深度融合,推动制造业迈向智能化、数字化新时代。AI通过智能生产调度、设备故障预测、质量检测和供应链优化等应用,显著提升效率和创新能力。特斯拉和富士康的智能工厂展示了AI在实际生产中的巨大潜力。然而,数据质量、技术集成和人才短缺等问题仍需解决。未来,AI将与5G、物联网等技术融合,进一步推动工业制造全面升级。
1123 9
|
人工智能 编解码 算法
全球顶级赛事实践:视频云制播在奥运赛事的关键技术与创新
本次分享主题为“全球顶级赛事实践:视频云制播在奥运等体育赛事的关键技术与创新”。内容涵盖视频云制播的整体技术框架、AI技术重构体育赛事全链路、视频云制播+AI的技术创新与应用、未来展望,以及央视频在奥运等赛事中的成功实践。通过阿里云和央视频的合作,展示了多语种解说、多视角同步、智能媒资管理等技术创新,提升了观众的观赛体验,并推动了体育赛事转播的智能化发展。
1023 0
|
搜索推荐 编译器 开发者
应用程序的运行:原理、过程与代码实践
应用程序的运行:原理、过程与代码实践
799 1