设计模式【结构型】-- 装饰者模式

news2024/12/23 17:37:17

装饰模式(Decorator Pattern)

定义

装饰者模式是一种结构型设计模式,它允许你动态地将新功能添加到对象中,通过将对象放入包含这些功能的特殊包装器对象中。这样一来,你可以在运行时通过组合不同的对象来扩展功能,而不是通过继承修改代码。

大白话装饰模式,是指在不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)

装饰(Decorator)模式中的角色:

  • 抽象构件(Component)角色 :定义一个抽象接口以规范准备接收附加责任的对象。
  • 具体构件(Concrete Component)角色 :实现抽象构件,通过装饰角色为其添加一些职责。
  • 抽象装饰(Decorator)角色 : 继承或实现抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
  • 具体装饰(ConcreteDecorator)角色 :实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

案例

以下是装饰者模式在Java中的示例代码:

// 定义一个组件接口
interface Component {
    void operation();
}

// 具体组件实现类
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("执行具体操作");
    }
}

// 装饰者抽象类
abstract class Decorator implements Component {
    protected Component component;

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

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

// 具体装饰者类A
class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

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

// 具体装饰者类B
class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

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

// 使用示例
public class Main {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        component.operation();

        System.out.println("-------------------");

        Component decoratedComponent = new ConcreteDecoratorA(new ConcreteDecoratorB(new ConcreteComponent()));
        decoratedComponent.operation();
    }
}

在这里插入图片描述

案例分析说明

在上述代码中,Component 是组件接口,定义了一个 operation 方法。ConcreteComponent 是具体组件实现类,实现了 Component 接口并实现了具体操作。

Decorator 是装饰者抽象类,实现了 Component 接口,并维护一个 Component 对象作为成员变量。Decorator 类的 operation 方法会在调用其包含的组件的 operation 方法之前或之后添加额外的功能。

ConcreteDecoratorAConcreteDecoratorB 是具体装饰者类,分别继承自 Decorator 类。它们在调用父类的 operation 方法后,添加了不同的额外功能。

Main 类的示例中,我们首先创建了一个 ConcreteComponent 对象,并调用其 operation 方法。然后,我们使用装饰者模式创建了一个具有多层装饰的对象,并调用其 operation 方法。可以看到,每个装饰者在执行完自身的操作后,会继续调用下一个装饰者或具体组件的操作。

优点:

现在,让我们来比较装饰者模式和继承的优缺点及适用场景:

  1. 装饰者模式可以动态地添加或删除对象的功能,而无需修改现有代码,更具灵活性。
  2. 装饰者模式遵循开闭原则,即对扩展开放、对修改关闭。你可以通过增加新的装饰者类来扩展功能,而不是修改已有类的代码。
  3. 装饰者模式避免了使用大量的继承来扩展功能,减少了类的个数,提高了代码的可读性和维护性。

缺点:

  1. 使用装饰者模式会增加许多小对象,如果过度使用,可能会导致系统复杂性增加。
  2. 装饰者模式在设计时需要注意顺序,因为装饰者是通过嵌套组合的方式实现的。如果顺序不正确,可能会影响到最终的结果。

适用场景:

  1. 当你需要在不修改现有对象的情况下,动态地为对象添加额外功能时,可以使用装饰者模式。
  2. 当你有多个相互独立的扩展方案,且可能需要组合使用时,装饰者模式比继承更灵活。
  3. 当你希望根据需要透明地、逐级地给对象添加功能时,装饰者模式非常适用。

总结

总结起来,装饰者模式通过组合而不是继承来实现功能的扩展,使得代码更加灵活、可扩展,并符合开闭原则。它适用于需要动态地为对象添加功能、避免使用过多继承、以及逐级透明地给对象添加功能的情况。

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

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

相关文章

用手机号注册亚马逊买家号需要注意什么问题

亚马逊平台的买家号可以用手机号注册也可以用邮箱进行注册,注册方法都是打开官网后点击注册,根据提示输入账号信息。当使用手机号注册亚马逊买家号时,有一些问题需要注意: 1、确保手机号的准确性:正确的手机号码非常重…

Android 系统的分区介绍

由于Android系统采用Linux架构,所以Android的系统分区可以类比同样采用Linux架构的操作系统(如Windows)。 Android系统分区分类 现在一般常见的Android分区方式共有三种,在不同的Android系统版本上会采用不同的分区方式。 1、传…

CentOS 7.8 Oracle 19C安装部署

CentOS 7.8 Oracle 19C安装部署 一、环境检查1、操作系统检查2、内存检查3、SWAP检查4、共享内存检查5、磁盘空间检查 二、YUM配置及RPM依赖包安装1、YUM源搭建2、 RPM依赖包安装 三、创建组、用户、目录1、创建组、用户2、创建目录 四、系统参数配置1、关闭防火墙2、配置域名解…

跟我一起从零开始学python(七)机器学习

前言 回顾之前讲了python语法编程 ,必修入门基础和网络编程,多线程/多进程/协程等方面的内容,昨天和今天讲到了数据库编程篇MySQL,Redis今天第三篇MongoDB篇,前面没看的也不用往前翻,系列文已经整理好了&a…

【Axure高保真原型】美化滚动条模板

今天和大家分享美化滚动条的原型模板,包括美化动态面板滚动条、页面滚动条、内联框架滚动条,其中内联框架滚动条是通过美化对应调用的页面的滚动条而美化,并不是直接美化内联框架的滚动条。具体效果可以观看下方视频或者打开预览地址体验&…

个人微信开发API,微信机器人。

微信个人号二次开发,基于API开发可以有很多功能模块 各种知名SCRM系统、客服平台都是根据此API二次开发的。 在这里插入图片描述 好友管理: 添加好友、 删除好友、 修改备注、 创建标签、 获取好友列表、 检测僵尸粉 设置个人头像 同意添加好友 获取好…

【面试题38】linux下面chmod和chown使用详解

文章目录 一、前言二、什么是 chmod 命令?2.1 使用方法:2.2 数值表示法:2.3 符号表示法: 三、什么是 chown 命令?3.1 使用方法:3.2 更改所有者和用户组: 四、使用示例4.1 使用 chmod 命令修改权…

想要逼疯项目经理,真的太简单了

早上好,我是老原。 最近有个小友来找我吐槽,说太崩溃了,带个项目太不容易了…… 此情此景,我已经脑补了各种抱头痛哭流涕的画面,油然升起一股同情。 其实,项目经理,听起来是个经理&#xff0…

echarts条形图动态显示2

1、实现效果,条形图自动滚动,鼠标移入停止滚动,移出继续滚动 2、代码 声明的变量:图表,图表数据与定时器 myChartArea: , dataArea: {categoryData: [],valueData: [],fullData: [], }, timeOut: null,设…

【无公网IP端口映射】远程访问本地jupyter notebook服务

文章目录 前言1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 前言 Jupyter Notebook,它是一个交互式的数据科学和计算环境,支持多种编程语言,如…

Devchat让代码爽飞

Devchat让代码爽飞 安装python3安装vscode中安装devchat插件使用参考资料 devchat是一个免费的vscode插件,可以在vsocde中提示代码。 安装 devcha依赖于python3,首先需要再电脑中安装python3.然后在vscode中安装插件,然后利用python安装dev…

canal探索及应用

认识canal 译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费 早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010 年…

冷门研究冒险家同济陈涵晟:让科技帮助未来人类拓展艺术边界

原来他们是这样走过来的! 【AI红人荟】——这里是TechBeat人工智能社区为优秀的AI工作者开设的人物专访栏目。从膜拜“红人”到成为“红人”,TechBeat与你一起,在AI进阶之路上,升级打怪、完美通关~ 本篇人物,是来自同…

消息中间件RabbitMQ详解

一、 消息中间件 简介 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。 使用环境 消息中间件适用于需要可靠的数据传送…

超细整理,接口自动化测试-DDT参数化驱动实战,一招打通...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 ddt说明 一般进行…

MySQL数据库——索引练习

一、练习题目 1、建立一个utf8编码的数据库test1 2、建立商品表goods和栏目表category(要求:按如下表结构创建表,并且存储引擎engine myisam 字符集charset utf8) 3、删除 goods 表中的 goods_desc 字段及货号字段,并增加 click…

JMeter中如何实现接口之间的关联?

关联是Jmeter工具中非常重要的一个技术。因为在测试过程过有些数据是经常发生变化的,要获取并使用这些数据,就要使用关联。 比如:用户登录后,session信息都不同,有些操作要使用session,就需要将这个动态的…

【国产复旦微FMQL45教程】-Procise应用流程

本教程采用 FMQL7045 FPGA开发板来完成整个试验,板卡照片如下: 具有丰富的接口资源,系统框图如下: 本教程用于完成基于Vivado的FMQL45的LED实验,目标是能够将这款开发板PL端先跑起来。 2 Procise工程建立 &#xff0…

AI绘画在线生成!推荐这个国产Midjourney平替

AI技术越来越成熟,不仅能生成文本,还能绘画。AI绘画软件层出不穷,很多人接触的是Midjourney。我之前也用过Midjourney,确实在作品精确度、图像细节等方面很出色。但用Midjourney需要有良好的网络,而且必须得是会员。 因…

Mysql常用存储引擎------MyISAM存储引擎

文章目录 一、MyISAM存储引擎1、1加锁与并发2、1修复3、1索引特性3、4 延迟更新索引键3、5 MyISAM 压缩表3、6 MyISAM 性能 二、MySQL 存储引擎 MyISAM 与 InnoDB 如何选择?一、InnoDB支持事务,MyISAM不支持,这一点是非常重要。事务是一种高级…