java设计模式之装饰器设计模式

news2025/7/23 6:31:42

介绍

装饰器设计模式是一种结构型设计模式,它允许动态地将行为添加到对象中,而无需在对象的类中使用子类化。它允许您通过将对象封装在一个具有新行为的对象中来动态地修改对象的行为。
这种模式是基于组合的思想,而不是继承。
可动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

在这篇文章中,我们将深入探讨Java中的装饰器设计模式,包括模式的定义、使用场景和一个实际的案例。

定义

装饰器模式可以理解为在不改变原有对象结构的前提下,通过动态地为对象添加新的行为来扩展对象的功能。这种模式通过将对象包装在装饰器对象中来实现。

使用场景

装饰器设计模式在以下情况下非常有用:

  • 需要动态地向对象添加行为,而不是静态地添加它们。
  • 需要通过将许多小型对象组合成更大的对象来创建复杂的对象。
  • 需要增强现有对象的功能,而不是创建新的子类来实现它。

装饰器模式的结构

在这里插入图片描述

1、Component,抽象构件

Component是一个接口或者抽象类,是定义我们最核心的对象,也可以说是最原始的对象,比如街边小吃;

2、ConcreteComponent,具体构件,或者基础构件

ConcreteComponent是最核心、最原始、最基本的接口或抽象类Component的实现,可以单独用,也可将其进行装饰;

3、Decorator,装饰角色

一般是一个抽象类,继承自或实现Component,在它的属性里面有一个变量指向Component抽象构件,这是装饰器最关键的地方。

4、ConcreteDecorator,具体装饰角色

牛奶咖啡和加糖牛奶咖啡是两个具体的装饰类,它们可以把基础构件装饰成新的东西,比如把一个普通的咖啡装饰成加牛奶、加糖的咖啡。

优缺点:

优点:

可以在不改变现有代码的情况下向对象添加功能,从而使代码更加灵活和可扩展。
可以通过组合不同的装饰器来创建具有不同功能集的对象,这样可以避免类爆炸问题。
装饰器可以嵌套使用,使得功能的组合更加灵活,可以根据需要组合不同的功能。

缺点:

使用装饰器会增加代码的复杂性,尤其是在需要嵌套多个装饰器时。
可能会导致运行时的性能损失,因为每个装饰器都需要在运行时动态地修改对象的行为。
如果使用不当,装饰器可能会导致代码可读性和维护性下降,特别是在使用多个装饰器时。

咖啡案例

首先,我们定义一个抽象的咖啡类,它有一个名字和一个价格:

public abstract class Coffee {
    protected String name;
    protected double price;

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

然后,我们定义一个具体的咖啡类,它继承自抽象咖啡类:

public class Espresso extends Coffee {
    public Espresso() {
        name = "浓咖啡";
        price = 2.0;
    }
}

现在,我们可以使用装饰者模式来为咖啡添加配料。我们首先定义一个抽象的配料装饰器类

public abstract class CoffeeDecorator extends Coffee {
    protected Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    public String getName() {
        return coffee.getName() + " + " + name;
    }

    public double getPrice() {
        return coffee.getPrice() + price;
    }
}

这个类包含了一个抽象的咖啡对象,它将被添加配料。然后,我们可以定义具体的配料装饰器类,它们

继承自配料装饰器类:

public class Milk extends CoffeeDecorator {
    public Milk(Coffee coffee) {
        super(coffee);
        name = "牛奶";
        price = 0.5;
    }
}

public class Sugar extends CoffeeDecorator {
    public Sugar(Coffee coffee) {
        super(coffee);
        name = "加糖";
        price = 0.3;
    }
}

public class Caramel extends CoffeeDecorator {
    public Caramel(Coffee coffee) {
        super(coffee);
        name = "焦糖";
        price = 0.7;
    }
}

现在,我们可以创建具体的咖啡对象,并添加各种配料:

Coffee espresso = new Espresso();
espresso = new Milk(espresso);
espresso = new Sugar(espresso);
espresso = new Caramel(espresso);
System.out.println(espresso.getName() + ": " + espresso.getPrice());

输出结果将是:
在这里插入图片描述

装饰器模式在Java I/O系统中的实现

Java I/O类库就采用到了装饰器设计模式,以InputStream为例简单说明一下
在这里插入图片描述
InputStream作为抽象构件,其下面大约有如下几种具体基础构件,从不同的数据源产生输入:

  • ByteArrayInputStream,从字节数组产生输入;
  • FileInputStream,从文件产生输入;
  • StringBufferInputStream,从String对象产生输入
  • PipedInputStream,从管道产生输入;
  • SequenceInputStream,可将其他流收集合并到一个流内;

FilterInputStream作为装饰器在JDK中是一个普通类,其下面有多个具体装饰器
比如BufferedInputStream、DataInputStream等。我们以BufferedInputStream为例,使用它就是避免每次读取时都进行实际的写操作,起着缓冲作用。

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

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

相关文章

CFS三层内网渗透

目录 环境搭建 拿ubuntu主机 信息收集 thinkphp漏洞利用 上线msf 添加路由建立socks代理 bagecms漏洞利用 拿下centos主机 msf上线centos 添加路由,建立socks代理 拿下win7主机 环境搭建 设置三块虚拟网卡 开启虚拟机验证,确保所处网段正确&a…

展会邀约 | 昂视与您相约BTF第12届上海锂电展

BTF第12届上海国际新能源锂电展将于3月7日在上海新国际博览中心举办。此次展会以“锂想动力,共创未来”为主题,汇聚行业内一众翘楚企业与专业观众,为各位展商以及观众提供专业的锂电交流平台,了解与碰撞新产品、新技术与解决方案&…

APISIX网关系列之Dashboard配置路由(二)

APISIX网关系列之Dashboard配置路由(二) 1.概述 APISIX作为系列介绍,将它所有的功能按照职责划分输出到每篇文章中。 上篇文章作为系列的开篇文章对APISIX进行了分析和安装介绍,查看详情地址:https://blog.csdn.net/m0_38039437/article/de…

【经典数据结构OJ讲解】你知道如何用两个队列实现一个栈,如何用两个栈实现一个队列吗?

目录 0.前言 1.回顾什么是队列和栈 2.如何用两个队列实现一个栈 2.1思路讲解 2.2按照思路实现仿生栈的各接口 2.2.1栈的初始化 2.2.2栈的销毁 2.2.3栈的插入 2.2.4栈的删除 2.2.5 栈的栈顶数据 2.2.6 判断当前栈是否为空 3.如何用两个栈实现一个队列 3.1 思路分析…

梯度下降优化器:SGD -> SGDM -> NAG ->AdaGrad -> AdaDelta -> Adam -> Nadam -> AdamW

目录 1 前言 2 梯度概念 3 一般梯度下降法 4 BGD 5 SGD 6 MBGD 7 Momentum 8 SGDM(SGD with momentum) 9 NAG(Nesterov Accelerated Gradient) 10 AdaGrad 11 RMSProp 12 Adadelta 13 Adam 13 Nadam 14 AdamW 15 Lion(EvoLve…

js 实现 Logo(图片)根据图片后面的图片颜色而变化成相反的颜色【解决logo固定后 会出现与不同板块的颜色相同导致于看不清logo的情况】

效果展示&#xff1a; <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <meta http-equiv"X-UA-Compatible" content"ieedge"><style type"text/css…

进程概念(二)

文章目录进程概念&#xff08;二&#xff09;1. 进程状态1.1 阻塞和挂起状态1.2 进程状态1.2.1 进程查看S状态R状态1.2.2 D状态1.2.3 T状态1.2.4 t状态1.2.5 Z状态(僵尸状态)1.3 孤儿进程2. 环境变量2.1 背景2.2 认识环境变量2.3 获取环境变量2.4 环境变量是什么2.5 认识命令行…

vue:pdf.js使用细节/隐藏按钮/设置、获取当前页码/记录阅读进度/切换语言(国际化)

需求描述 在网页中预览pdf时&#xff0c;希望实现3点需求&#xff1a;1、隐藏一些功能按钮&#xff08;比如下载&#xff09;&#xff1b;2、打开pdf时自动定位到最后浏览的页&#xff08;记录阅读进度&#xff09;&#xff1b;3、实现国际化&#xff08;在代码中更改pdf插件使…

Java面试题-Spring框架

Spring框架 1. BeanFactory和ApplicationContext有何区别 BeanFactory是Spring最底层的接口&#xff0c;是IoC的核心&#xff0c;定义IoC的基本功能。 ​ BeanFactory具有&#xff1a;延迟实例化的特性。在启动的时候&#xff0c;不会实例化Bean&#xff0c;只有有需要从容器…

ESMM的理解和高频面试问题

ESMM的理解首先&#xff0c;理解部分主要是ESMM要解决什么问题&#xff0c;以及解决方案。弱未度过原文的可以查阅原论文。论文地址&#xff1a;https://arxiv.org/pdf/1804.07931.pdf实现代码&#xff1a;https://github.com/PaddlePaddle/PaddleRec/tree/master/models/multi…

2023最新谷粒商城笔记之购物车篇(全文总共13万字,超详细)

购物车 环境搭建 创建购物车项目 第一步、创建gulimall-cart服务&#xff0c;并进行降版本处理 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.8.RELEASE<…

angular框架表格自定义导出,ui组件库为【devExpress by devExtreme】导出插件为exceljs、file-saver

前言 使用的ui组件库为devExtreme注意&#xff1a;如果你没有使用这个组件库&#xff0c;那后续的代码可能对你不适用&#xff01;&#xff01;&#xff01;&#xff0c;因为devExtreme和exceljs是结合着来的 其地址如下&#xff1a; devexpress https://js.devexpress.com/ …

一文速学-Pandas查询索引操作详解+实例代码展示

目录 前言 一、按列表索引查询 查询单值 1.at(单值查询-loc) 2.iat(单值查询-iloc) 3. loc(行/列名索引查询) 4. iloc(行/列索引查询) 二、按条件查询 单条件查询 多条件查询 嵌套筛选 总结 前言 关于一文速学Pandas系列已经将基础部分内容更完&#xff0c;基础部分的…

ASEMI高压MOS管ASE65R330参数,ASE65R330图片

编辑-Z ASEMI高压MOS管ASE65R330参数&#xff1a; 型号&#xff1a;ASE65R330 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;650V 栅源电压&#xff08;VGS&#xff09;&#xff1a;20V 漏极电流&#xff08;ID&#xff09;&#xff1a;12.5A 功耗&#xff08;P…

[数据结构]:03-栈(C语言实现)

目录 前言 已完成内容 单链表实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-StackCommon.cpp 04-StackFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容&#xff0c;除其中使用到C引用外&#xff0c;全为C语言代码。使用C引用主要是为了简…

跨境卖家必看的沃尔玛Walmart商家入驻教程

沃尔玛Walmart作为作为全球连锁超市的鼻祖&#xff0c;有不可比拟的知名度。当沃尔玛从线下延伸到线上后&#xff0c;就成为一个自带IP与流量的线上平台&#xff0c;在全世界都拥有数量庞大的消费者群体。所以龙哥就结合自己注册Walmart的过程给大家详细讲解一下。 Walmart卖家…

365智能云打印怎么样?365小票无线订单打印机好用吗?

365智能云打印怎么样&#xff1f;365智能云打印是有赞官方首推的订单小票打印机&#xff0c;荣获2016年有赞最佳硬件服务商。可以实现远程云打印&#xff0c;无需连接电脑&#xff0c;只需通过GPRS流量或者WIFI即可连接&#xff0c;不受地理位置和距离限制。365小票无线订单打印…

1W+企业都在用的数字化管理秘籍,快收藏!

企业数字化&#xff0c;绕不开的话题。 随着国家相继出台各种举措助力中小企业数字化转型&#xff0c;积极推动产业数字化转型&#xff0c;培育数字经济新生态&#xff0c;企业想要谋生存&#xff0c;求发展&#xff0c;必然需要做好数字化转型和管理。 本篇文章想跟大家一起…

【STM32MP157应用编程】2.GPIO输入、输出、中断

目录 GPIO文件 指令操作GPIO 程序操作GPIO 程序说明 程序代码 2_GPIO_4.c 启动交叉编译工具 编译 拷贝到开发板 测试 GPIO文件 在/sys/class/gpio目录下&#xff0c;存放了GPIO的文件。 gpiochipX&#xff1a;当前SoC所包含的GPIO控制器&#xff0c;STM32MP157一共包…

新型开源C2框架:浩劫

研究人员发现了一次针对政府实体的新攻击&#xff0c;攻击者在此期间使用了一种名为浩劫&#xff08;Havoc &#xff09;的新型 C2 框架。 尽管 C2 框架广泛可用&#xff0c;但 Havoc 作为一种先进的后开发框架脱颖而出&#xff0c;可以躲避最新版本的 Windows 11 Defender。 …