Java设计模式-装饰模式

news2024/11/13 10:03:21

简介

装饰模式在Java领域是一种常见的设计模式,它能够在不改变对象原有结构的情况下,动态地为对象添加新的功能。它通过封装原有对象,在运行时动态地为对象添加新的行为或者修改原有行为,以扩展对象的功能。这种方式避免了继承的静态特性,让对象的行为可以根据需要进行动态变化。在装饰模式中,通常会有一个装饰器类,该类继承自要被装饰的对象,然后在运行时为对象添加新的功能。
在设计模式中,装饰模式与其他几种常见的设计模式有一些相似之处,例如适配器模式、代理模式和桥接模式。这些模式都是为了改变对象的行为而提供了解决方案,但它们与装饰模式的主要区别在于:

  1. 适配器模式:适配器模式用于连接两个不兼容的接口。它将一个类的接口转换为另一个接口,以适应另一个类的需求。适配器模式通常在应用程序中解决不兼容的接口问题。

  2. 代理模式:代理模式用于控制对对象的访问。它允许在不改变对象的结构的情况下控制对对象的访问,以提供安全性和性能方面的好处。代理模式通常用于实现远程对象访问、访问控制和缓存等功能。

  3. 桥接模式:桥接模式用于将一个抽象类与多个实现类解耦。它将一个抽象类与多个实现类分离开来,以使它们可以独立地进行修改和扩展。桥接模式通常用于实现可扩展的类层次结构。
    img

实现

现在,我们来看看如何使用Java编程语言实现装饰模式。

首先,我们需要定义一个接口或者抽象类来定义要被装饰的对象。例如,我们可以定义一个抽象类Component,它包含一个抽象方法operation(),表示该对象的操作。具体实现可以根据业务需求进行扩展。

public abstract class Component {
    public abstract void operation();
}

然后,我们需要定义具体的对象类,实现Component接口或者继承Component抽象类。例如,我们可以定义一个具体的对象类ConcreteComponent,它实现了Component接口,实现了operation()方法。

public class ConcreteComponent extends Component {
    @Override
    public void operation() {
        System.out.println("执行具体对象的操作");
    }
}

接下来,我们需要定义一个装饰器类Decorator,它继承自Component类,并包含一个Component类型的成员变量,表示要被装饰的对象。它的构造函数可以接收一个Component类型的参数,用于初始化成员变量。

public class Decorator extends Component {
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}

最后,我们可以定义具体的装饰器类,它继承自Decorator类,并扩展了要被装饰的对象的功能。例如,我们可以定义一个具体的装饰器类ConcreteDecorator,它添加了新的功能,例如在原有操作前或者后输出一些信息。

public class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        System.out.println("添加新的功能");
        super.operation();
    }
}

现在,我们就可以使用装饰模式来扩展对象的功能了。例如,我们可以创建一个具体对象component,然后用装饰器类ConcreteDecorator来装饰它,以添加新的功能。

Component component = new ConcreteComponent();
Component decorator = new ConcreteDecorator(component);
decorator.operation();

在运行以上代码后,我们可以看到控制台输出了以下信息:

添加新的功能
执行具体对象的操作

优缺点

优点

  1. 装饰模式可以动态地为对象添加新的功能,而不需要修改原有的代码。这种方式可以让代码更加灵活和可扩展。
  2. 装饰模式避免了继承的缺点,例如类层次结构的膨胀和代码的复杂性,使得代码更加简洁和易于维护。
  3. 装饰模式可以嵌套使用,以实现更加复杂的功能。

缺点

  1. 装饰模式增加了代码的复杂性,需要增加许

多的类和对象,这可能会使代码难以理解和维护。

  1. 装饰模式增加了系统的运行时开销,因为每个装饰器都要增加一些额外的处理。

运用场景

  1. 当需要动态地为对象添加新的功能时,可以考虑使用装饰模式。
  2. 当不希望使用继承来扩展对象的功能时,可以考虑使用装饰模式。
  3. 当需要在不修改原有代码的情况下,增加一些新的功能时,可以考虑使用装饰模式。

总结

装饰模式是一种非常有用的设计模式,它可以动态地为对象添加新的功能,而不需要修改原有的代码。通过定义一个抽象的装饰器类和具体的装饰器类,我们可以非常方便地扩展对象的功能,以满足不同的业务需求。虽然装饰模式增加了代码的复杂性和运行时开销,但是它在许多情况下仍然是一种非常有效的解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/512405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言:简单的三子棋游戏

谈到三子棋,想必大家都不陌生,童年的回忆呀,读小学的时候有事没事就和同学玩上个几把,玩起来很得劲,作为一个学习计算机的博主,自然而然用代码来实现三子棋啦,再次感受童年的记忆,闲…

yolov8 实例分割 C++部署

此处仅为个人结果记录,并无完整部署代码 目录 Pre 一、OpenCV DNN C 部署 二、ONNX RUNTIME C 部署 Pre 一定要知道,yolov8的输出与Yolov5 7.0 实例分割的输出不一样, output0: float32[1,116,8400]。 116是4个box坐标信息80个类别概率…

政务场景|看「API-SMAC」如何守好API,保障流动数据安全

API让一切都变得更加容易。 在数字化进程加速中,API作为高速通道,让数据的流动变得更加自由。当然,黑客也这么认为。从前窃取数据需要攻入内网,再经过一系列复杂的横向移动最终访问目标数据库,极易被安全设备拦截。现在…

endNote X9 增加 / 删除参考文献 文献编号自动更新

文章目录 1 增插参考文献2 删减参考文献3 EndNote X9 插入参考文献常见问题总结4 EndNote X9 快速上手教程(毕业论文参考文献管理器) 1 增插参考文献 当前已经插入5个文献,文献编号及附录列表如下 例如在,2和3之间新插入文献 “邱…

基于粒子群优化算法的最佳方式优化无线传感器节点的位置(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 此代码优化了由于电池耗尽而产生覆盖空洞后 WSN 节点的位置。如果活动通信中的任何节点死亡,则通过PSO优化再次定位…

动态联编和静态联编

基本概念 1.静态联编(早联编):在程序被编译时进行联编。程序执行快,但灵活性较小。 2.动态联编(晚联编,滞后联编):编译时无法确定要调用的函数,在程序运行时联编。灵活…

代码随想录算法训练营day37 | 738.单调递增的数字,968.监控二叉树

代码随想录算法训练营day37 | 738.单调递增的数字,968.监控二叉树 738.单调递增的数字968.监控二叉树(难) 738.单调递增的数字 教程视频:https://www.bilibili.com/video/BV1Kv4y1x7tP/?spm_id_from333.788&vd_sourceddffd5…

Pytorch环境下基于Transformer的滚动轴承故障诊断

关于python的集成环境,我一般Anaconda 和 winpython 都用,windows下主要用Winpython,IDE为spyder(类MATLAB界面)。 winpython脱胎于pythonxy,面向科学计算,兼顾数据分析与挖掘;Anaco…

如何恢复数据?数据恢复,5个实用方法!

案例:如何恢复数据 【我是个比较粗心的人,总是会莫名奇妙的就丢失各种电脑的数据,想问下大家在使用电脑时,如果有数据的丢失,是如何恢复数据的呢?】 在使用Windows电脑时,数据丢失或删除是非常…

支付系统设计二:统一开发框架

文章目录 前言一、项目分层二、模块职责简介1. API层2. Service层2.1 操作执行服务2.2 操作器2.3 操作执行器2.4 参数校验2.5 操作器实现 3. Domain层4. Infrastructure层4.1 Dal层 三、对应类图四、开发内容3.1 约定请求报文格式3.2 新增交易码与操作器映射枚举类3.3 配置参数…

2 # 函数柯里化

什么是函数柯里化 函数柯里化(Currying)是一种将接受多个参数的函数转换为一系列接受单一参数的函数的技术。 通过函数柯里化,我们可以将原来接受多个参数的函数,转换为一系列只接受单一参数的函数,每个函数接收一个…

前端面试题总结(初级前端:HTML + CSS + JavaScript + Ajax + Vue2全家桶)

theme: channing-cyan 求关注😭 壹、HTML CSS 1. 对HTML语义化的理解 去掉或者丢失样式的时候能够让页面呈现出清晰的结构;代码结构清晰,方便团队的管理和维护,并且语义化更具可读性;提升用户体验,在…

什么是daemon与服务(service)

什么是daemon与服务(service) 在Linux系统中,daemon是指一类在后台运行的服务进程,通常以d结尾。它们不与用户进行交互,也不接受用户的输入,而是在系统启动时自动启动并一直运行,为操作系统、应用程序和其他服务提供支…

Julia入门-3、Julia包管理工具

文章目录 0、Julia 的包管理工具是Pkg1、使用Julia包管理工具过慢 0、Julia 的包管理工具是Pkg Julia 的包管理工具是Pkg,可以用于安装、更新、卸载和管理 Julia 中的软件包。以下是一些常用的 Pkg命令: Pkg.add("Package"):安装一…

Node.js 与 WebAssembly

目录 1、简介 2、关键概念 3、生成WebAssembly模块 4、如何使用它 5、与操作系统交互 1、简介 首先,让我们了解为什么WebAssembly是一个很棒的工具,并学会自己使用它。 WebAssembly是一种类似汇编的高性能语言,可以从各种语言编译&…

深度学习 - 47.DIN 深度兴趣网络保姆级实现 By Keras

目录 一.引言 二.DIN 模型分析 1.Input 输入 2.Embedding & Concat 嵌入与合并 3.DIN 深度兴趣网络 4.MLP 全连接 三.DIN 模型实现 1.Input 2.DIN Layer 2.1 init 初始化 2.2 build 构建 2.3 call 调用 3.Dice Layer 3.1 init 初始化 3.2 build 构建 3.3 …

网络安全:渗透神器 kali 的安装.

网络安全:渗透神器 kali 的安装. Kali Linux是一款基于Debian的Linux发行版,专门用于渗透测试和网络安全评估。它包含了大量的渗透测试工具和网络安全工具,适用于各种不同的渗透测试场景和需求。 目录: 网络安全:渗透…

MS5814可选内置基准、四通道数模转换器

MS5814/5814T 是一款 12bit 四通道输出的电压型 DAC,集成可选内部基准,接口采用四线串口模式,可以兼容 TMS320、SPI、QSPI 和 Microwire 串口。MS5814/5814T 控制数据有 16bit,包括 DAC 地址,控制字节和 12bitDAC 数据…

MySQL——BasicKnowledge

1. Mysql Version ​​​​​​​​​​​​ 2.install & uninstall 2.1 Linux My Content 3.Configure 3.1 设置IP访问 参考链接 3.1.1 方法一:改表法 --登入mysql后,更改"mysql"数据库中"user"表里的 "host&quo…

“三问五步”落地医疗行业数据安全建设体系|盾见

个 文|龚磊 2021年6月10日,我国《数据安全法》颁布,并于2021年9月1日正式施行,作为数据领域的纲领性和基础性法律,以准确定义数据、数据处理、数据安全为出发点,提出解决数据全生命周期中的数据安全问题,达…