二十三种设计模式-装饰器模式
一、定义与核心思想
装饰器模式是一种结构型设计模式,其核心思想是动态地给一个对象添加一些额外的职责。通过这种方式,可以在不改变原有对象结构的基础上,灵活地增加新的功能,使得对象的行为可以得到扩展,同时又保持了原有类的简洁性。
二、组成要素
装饰器模式主要由以下几个要素组成:
-
抽象组件(Component)
-
这是一个接口或抽象类,用于定义对象的接口,即声明了所有具体组件和装饰器类都需要实现的方法。它使得装饰器类可以与被装饰的具体组件类在接口上保持一致,从而可以在运行时动态地组合对象。
-
例如,定义一个
Component接口,其中声明了一个operation()方法。
-
-
具体组件(ConcreteComponent)
-
实现抽象组件接口的具体类,它定义了对象的基本行为和状态,是被装饰的具体对象。
-
例如,
ConcreteComponent类实现了Component接口,在operation()方法中实现了具体的功能。
-
-
抽象装饰器(Decorator)
-
也实现了抽象组件接口,它内部包含了一个对抽象组件的引用,通过这个引用可以调用被装饰对象的方法。抽象装饰器类中还定义了一些新的方法或属性,用于添加新的功能。
-
例如,
Decorator类实现了Component接口,并且有一个Component类型的成员变量component,在operation()方法中先调用component.operation(),然后添加新的行为。
-
-
具体装饰器(ConcreteDecorator)
-
继承自抽象装饰器类,实现了添加具体功能的方法。每个具体装饰器类都实现了在抽象装饰器中声明的添加功能的方法,并且可以有自己独特的功能。
-
例如,
ConcreteDecoratorA和ConcreteDecoratorB都是Decorator的子类,在它们的operation()方法中分别添加了不同的新功能。
-
三、实现示例
以下是使用Java语言实现装饰器模式的一个简单示例:
// 抽象组件接口
interface Component {void operation();
}// 具体组件类
class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("具体组件的操作");}
}// 抽象装饰器类
abstract class Decorator implements Component {protected Component component;public void setComponent(Component component) {this.component = component;}@Overridepublic void operation() {if (component != null) {component.operation();}}
}// 具体装饰器A类
class ConcreteDecoratorA extends Decorator {private String addedState;@Overridepublic void operation() {super.operation();addedState = "New State";System.out.println("具体装饰器A的操作");}
}// 具体装饰器B类
class ConcreteDecoratorB extends Decorator {@Overridepublic void operation() {super.operation();addedBehavior();System.out.println("具体装饰器B的操作");}private void addedBehavior() {// 添加新的行为}
}// 客户端代码
public class Client {public static void main(String[] args) {Component component = new ConcreteComponent();ConcreteDecoratorA decoratorA = new ConcreteDecoratorA();ConcreteDecoratorB decoratorB = new ConcreteDecoratorB();decoratorA.setComponent(component);decoratorB.setComponent(decoratorA);decoratorB.operation();}
}
在这个示例中,客户端代码首先创建了一个具体组件对象component,然后创建了两个具体装饰器对象decoratorA和decoratorB。通过setComponent方法将component对象与装饰器对象关联起来,并且装饰器对象之间也可以相互关联。最后调用decoratorB.operation()方法时,会依次调用decoratorA.operation()和component.operation()方法,并在每个装饰器中添加新的行为。
四、优点
-
扩展性好
-
可以通过添加新的装饰器类来扩展对象的功能,而无需修改原有的组件类代码,符合开闭原则。
-
-
灵活性高
-
可以根据需要动态地添加或组合不同的装饰器,以达到不同的功能效果,比静态继承方式更加灵活。
-
-
避免了复杂的继承关系
-
如果使用继承来扩展功能,可能会导致大量的子类产生,而装饰器模式可以避免这种情况,使系统更加简洁。
-
五、缺点
-
可能会产生很多小类
-
每个装饰器类都是一个小类,如果装饰器很多,可能会导致类的数量急剧增加,增加了系统的复杂性。
-
-
调试难度较大
-
由于装饰器的动态组合,可能会使得对象的行为变得难以跟踪和调试,特别是当装饰器层次较多时。
-
六、应用场景
-
功能扩展
-
当需要给一个对象动态地添加额外的功能时,如给文本组件添加边框、颜色、字体等装饰效果。
-
-
增强对象行为
-
在不改变原有对象的基础上,增强对象的行为,如在网络通信中,对数据进行加密、压缩等处理,可以通过装饰器模式动态地添加这些功能。
-
-
多层装饰
-
当需要对对象进行多层装饰,以组合出多种不同的功能效果时,装饰器模式能够很好地满足需求,如在构建复杂的用户界面组件时,通过多个装饰器来实现不同的视觉效果和交互行为。
-
相关文章:
二十三种设计模式-装饰器模式
一、定义与核心思想 装饰器模式是一种结构型设计模式,其核心思想是动态地给一个对象添加一些额外的职责。通过这种方式,可以在不改变原有对象结构的基础上,灵活地增加新的功能,使得对象的行为可以得到扩展,同时又保持…...
架构思考与实践:从通用到场景的转变
在当今复杂多变的商业环境中,企业架构的设计与优化成为了一个关键议题。本文通过一系列随笔,探讨了业务架构的价值、从通用架构到场景架构的转变、恰如其分的架构设计以及如何避免盲目低效等问题。通过对多个实际案例的分析,笔者揭示了架构设…...
Spring MVC(一)
RestController RestController 是由 Controller 和 ResponseBody 两个注解构成的。 Spring 启动的时候会扫描所有包含 Controller 或者 RestController 注解的类,创建出对外的接口,这样外界就可以从这里与服务器实现交互,如果没有这个注解…...
vue3使用tsx渲染复杂逻辑的表单
前置 目前的应用场景是:检查项目是树结构,有的项目还需要动态显示对应的子集 项目用的是uniappvue3tsvite生成的app tsx模版 统一渲染入口 <script lang"ts">import uniForms from dcloudio/uni-ui/lib/uni-forms/uni-forms.vueimport…...
python助力WRF自动化运行
对大部分人而言,特别是新用户,WRF模式的安装繁琐且不必要,可以作为后续进阶掌握的技能,本学习跳过繁琐的安装步骤,直接聚焦模式的运行部分,通过短平快的教学,快速掌握模式运行。进一步将python语…...
Windows 下 Postgres 安装 TimescaleDB 插件
Windows 下 Postgres 安装 TimescaleDB 插件 一、准备工作 安装 PostgreSQL:首先确保你已经在 Windows 系统中成功安装了 PostgreSQL 数据库。可以从 PostgreSQL 官方网站下载适合你系统的安装包,并按照安装向导进行安装。安装过程中,记住设…...
【Vim Masterclass 笔记21】S09L39:Vim 设置与 vimrc 文件的用法示例(二)
文章目录 S09L39 Vim Settings and the Vimrc File - Part 21 Vim 的配色方案与 color 命令2 map 命令3 示例:用 map 命令快速生成 HTML 代码片段4 Vim 中的 Leader 键5 用 mkvimrc 命令自动生成配置文件 写在前面 本篇为 Vim 自定义配置的第二部分。当中的每个知识…...
【Docker】Supervisor 实现单容器运行多服务进程
本文内容均来自个人笔记并重新梳理,如有错误欢迎指正! 如果对您有帮助,烦请点赞、关注、转发、订阅专栏! 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】(全…...
【网络协议】【http】【https】ECDHE-TLS1.2
【网络协议】【http】【https】ECDHE-TLS1.2 ECDHE算法 1.客户端和服务器端事先确定好使用哪种椭圆曲线,和曲线上的基点G,这两个参数都是公开的, 双方各自随机生成一个随机数作为私钥d,并与基点 G相乘得到公钥Q(QdG),…...
(十五)WebGL中gl.texImage2D函数使用详解
在 WebGL 中,gl.texImage2D 是一个非常关键的函数,用于将图像数据上传到 WebGL 上下文中并作为纹理对象的一部分。它允许你将图像、视频、画布等作为纹理源。理解如何使用 gl.texImage2D 是在 WebGL 中处理纹理的核心之一。 文章目录 gl.texImage2D 的基…...
CSS 颜色
所有浏览器都支持的颜色名 所有现代浏览器均支持以下 140 种颜色名称(单击颜色名称或十六进制值,可查看将以该颜色为背景颜色以及不同的文本颜色): 颜色名十六进制颜色值颜色AliceBlue#F0F8FFAntiqueWhite#FAEBD7Aqua#00FFFFAqu…...
C#,入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果
C#,入门教程(01)—— Visual Studio 2022 免费安装的详细图文与动画教程https://blog.csdn.net/beijinghorn/article/details/123350910 C#,入门教程(02)—— Visual Studio 2022开发环境搭建图文教程https://blog.csdn.net/beijinghorn/article/detail…...
杀死安装 CentOS-7-x86_64-DVD-1908
使用 VMware 安装 CentOS-7-x86_64-DVD-1908 CentOS是 reahat 的 免费版本,有了ubutun ,为什么还要使用 CentOS呢? 在linux 服务器实际开发中,大家都用的CentOS,因为两个原因,一个是免费,第二是…...
55.【5】BUUCTF WEB NCTF2019 sqli
进入靶场 输入admin 123 过滤的这么严格??? 过滤很严格,此时要么爆破,要么扫描 直接扫描,得到robots.txt 访问后又得到hint.txt 继续访问 图片内容如下 $black_list "/limit|by|substr|mid|,|admi…...
LeetCode 题目 2545. 根据第 K 场考试的分数排序
在本篇文章中,我们将探讨如何根据第 K 场考试的分数对学生进行排序。这个问题是 LeetCode 上的一个中等难度问题,涉及到排序算法和自定义比较函数的使用。 问题描述 解题思路 理解问题 首先,我们需要理解问题的核心:根据第 K 场…...
算法随笔_12:最短无序子数组
上一篇: 算法随笔_11: 字符串的排列-CSDN博客 题目描述如下: 给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。请你找出符合题意的最短子数组,并输出它的长度。…...
计算机毕业设计PySpark+Hadoop+Hive机票预测 飞机票航班数据分析可视化大屏 航班预测系统 机票爬虫 飞机票推荐系统 大数据毕业设计
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Linux-C/C++--初探linux应用编程概念
对于大多数首次接触 Linux 应用编程的读者来说,可能对应用编程(也可称为系统编程)这个概念并不 太了解,所以在正式学习 Linux 应用编程之前,笔者有必要向大家介绍这些简单基本的概念,从整体上认识 到应用编…...
用sklearn运行分类模型,选择AUC最高的模型保存模型权重并绘制AUCROC曲线(以逻辑回归、随机森林、梯度提升、MLP为例)
诸神缄默不语-个人CSDN博文目录 文章目录 1. 导入包2. 初始化分类模型3. 训练、测试模型,绘图,保存指标 1. 导入包 from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier, GradientBoostingClass…...
动手学大数据-3社区开源实践
目录 数据库概览: MaxComput: HAWQ: Hologres: TiDB: Spark: ClickHouse: Apache Calcite 概览 Calcite RBO HepPlanner 优化规则(Rule) 内置有100优化规则 …...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
