当前位置: 首页 > news >正文

二十三种设计模式-装饰器模式

一、定义与核心思想

装饰器模式是一种结构型设计模式,其核心思想是动态地给一个对象添加一些额外的职责。通过这种方式,可以在不改变原有对象结构的基础上,灵活地增加新的功能,使得对象的行为可以得到扩展,同时又保持了原有类的简洁性。

二、组成要素

装饰器模式主要由以下几个要素组成:

  1. 抽象组件(Component)

    • 这是一个接口或抽象类,用于定义对象的接口,即声明了所有具体组件和装饰器类都需要实现的方法。它使得装饰器类可以与被装饰的具体组件类在接口上保持一致,从而可以在运行时动态地组合对象。

    • 例如,定义一个Component接口,其中声明了一个operation()方法。

  2. 具体组件(ConcreteComponent)

    • 实现抽象组件接口的具体类,它定义了对象的基本行为和状态,是被装饰的具体对象。

    • 例如,ConcreteComponent类实现了Component接口,在operation()方法中实现了具体的功能。

  3. 抽象装饰器(Decorator)

    • 也实现了抽象组件接口,它内部包含了一个对抽象组件的引用,通过这个引用可以调用被装饰对象的方法。抽象装饰器类中还定义了一些新的方法或属性,用于添加新的功能。

    • 例如,Decorator类实现了Component接口,并且有一个Component类型的成员变量component,在operation()方法中先调用component.operation(),然后添加新的行为。

  4. 具体装饰器(ConcreteDecorator)

    • 继承自抽象装饰器类,实现了添加具体功能的方法。每个具体装饰器类都实现了在抽象装饰器中声明的添加功能的方法,并且可以有自己独特的功能。

    • 例如,ConcreteDecoratorAConcreteDecoratorB都是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,然后创建了两个具体装饰器对象decoratorAdecoratorB。通过setComponent方法将component对象与装饰器对象关联起来,并且装饰器对象之间也可以相互关联。最后调用decoratorB.operation()方法时,会依次调用decoratorA.operation()component.operation()方法,并在每个装饰器中添加新的行为。

四、优点

  1. 扩展性好

    • 可以通过添加新的装饰器类来扩展对象的功能,而无需修改原有的组件类代码,符合开闭原则。

  2. 灵活性高

    • 可以根据需要动态地添加或组合不同的装饰器,以达到不同的功能效果,比静态继承方式更加灵活。

  3. 避免了复杂的继承关系

    • 如果使用继承来扩展功能,可能会导致大量的子类产生,而装饰器模式可以避免这种情况,使系统更加简洁。

五、缺点

  1. 可能会产生很多小类

    • 每个装饰器类都是一个小类,如果装饰器很多,可能会导致类的数量急剧增加,增加了系统的复杂性。

  2. 调试难度较大

    • 由于装饰器的动态组合,可能会使得对象的行为变得难以跟踪和调试,特别是当装饰器层次较多时。

六、应用场景

  1. 功能扩展

    • 当需要给一个对象动态地添加额外的功能时,如给文本组件添加边框、颜色、字体等装饰效果。

  2. 增强对象行为

    • 在不改变原有对象的基础上,增强对象的行为,如在网络通信中,对数据进行加密、压缩等处理,可以通过装饰器模式动态地添加这些功能。

  3. 多层装饰

    • 当需要对对象进行多层装饰,以组合出多种不同的功能效果时,装饰器模式能够很好地满足需求,如在构建复杂的用户界面组件时,通过多个装饰器来实现不同的视觉效果和交互行为。

相关文章:

二十三种设计模式-装饰器模式

一、定义与核心思想 装饰器模式是一种结构型设计模式,其核心思想是动态地给一个对象添加一些额外的职责。通过这种方式,可以在不改变原有对象结构的基础上,灵活地增加新的功能,使得对象的行为可以得到扩展,同时又保持…...

架构思考与实践:从通用到场景的转变

在当今复杂多变的商业环境中,企业架构的设计与优化成为了一个关键议题。本文通过一系列随笔,探讨了业务架构的价值、从通用架构到场景架构的转变、恰如其分的架构设计以及如何避免盲目低效等问题。通过对多个实际案例的分析,笔者揭示了架构设…...

Spring MVC(一)

RestController RestController 是由 Controller 和 ResponseBody 两个注解构成的。 Spring 启动的时候会扫描所有包含 Controller 或者 RestController 注解的类,创建出对外的接口,这样外界就可以从这里与服务器实现交互,如果没有这个注解…...

vue3使用tsx渲染复杂逻辑的表单

前置 目前的应用场景是&#xff1a;检查项目是树结构&#xff0c;有的项目还需要动态显示对应的子集 项目用的是uniappvue3tsvite生成的app tsx模版 统一渲染入口 <script lang"ts">import uniForms from dcloudio/uni-ui/lib/uni-forms/uni-forms.vueimport…...

python助力WRF自动化运行

对大部分人而言&#xff0c;特别是新用户&#xff0c;WRF模式的安装繁琐且不必要&#xff0c;可以作为后续进阶掌握的技能&#xff0c;本学习跳过繁琐的安装步骤&#xff0c;直接聚焦模式的运行部分&#xff0c;通过短平快的教学&#xff0c;快速掌握模式运行。进一步将python语…...

Windows 下 Postgres 安装 TimescaleDB 插件

Windows 下 Postgres 安装 TimescaleDB 插件 一、准备工作 安装 PostgreSQL&#xff1a;首先确保你已经在 Windows 系统中成功安装了 PostgreSQL 数据库。可以从 PostgreSQL 官方网站下载适合你系统的安装包&#xff0c;并按照安装向导进行安装。安装过程中&#xff0c;记住设…...

【Vim Masterclass 笔记21】S09L39:Vim 设置与 vimrc 文件的用法示例(二)

文章目录 S09L39 Vim Settings and the Vimrc File - Part 21 Vim 的配色方案与 color 命令2 map 命令3 示例&#xff1a;用 map 命令快速生成 HTML 代码片段4 Vim 中的 Leader 键5 用 mkvimrc 命令自动生成配置文件 写在前面 本篇为 Vim 自定义配置的第二部分。当中的每个知识…...

【Docker】Supervisor 实现单容器运行多服务进程

本文内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01; 如果对您有帮助&#xff0c;烦请点赞、关注、转发、订阅专栏&#xff01; 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】&#xff08;全…...

【网络协议】【http】【https】ECDHE-TLS1.2

【网络协议】【http】【https】ECDHE-TLS1.2 ECDHE算法 1.客户端和服务器端事先确定好使用哪种椭圆曲线&#xff0c;和曲线上的基点G&#xff0c;这两个参数都是公开的&#xff0c; 双方各自随机生成一个随机数作为私钥d&#xff0c;并与基点 G相乘得到公钥Q(QdG)&#xff0c…...

(十五)WebGL中gl.texImage2D函数使用详解

在 WebGL 中&#xff0c;gl.texImage2D 是一个非常关键的函数&#xff0c;用于将图像数据上传到 WebGL 上下文中并作为纹理对象的一部分。它允许你将图像、视频、画布等作为纹理源。理解如何使用 gl.texImage2D 是在 WebGL 中处理纹理的核心之一。 文章目录 gl.texImage2D 的基…...

CSS 颜色

所有浏览器都支持的颜色名 所有现代浏览器均支持以下 140 种颜色名称&#xff08;单击颜色名称或十六进制值&#xff0c;可查看将以该颜色为背景颜色以及不同的文本颜色&#xff09;&#xff1a; 颜色名十六进制颜色值颜色AliceBlue#F0F8FFAntiqueWhite#FAEBD7Aqua#00FFFFAqu…...

C#,入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果

C#&#xff0c;入门教程(01)—— Visual Studio 2022 免费安装的详细图文与动画教程https://blog.csdn.net/beijinghorn/article/details/123350910 C#&#xff0c;入门教程(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 的 免费版本&#xff0c;有了ubutun &#xff0c;为什么还要使用 CentOS呢&#xff1f; 在linux 服务器实际开发中&#xff0c;大家都用的CentOS&#xff0c;因为两个原因&#xff0c;一个是免费&#xff0c;第二是…...

55.【5】BUUCTF WEB NCTF2019 sqli

进入靶场 输入admin 123 过滤的这么严格&#xff1f;&#xff1f;&#xff1f; 过滤很严格&#xff0c;此时要么爆破&#xff0c;要么扫描 直接扫描&#xff0c;得到robots.txt 访问后又得到hint.txt 继续访问 图片内容如下 $black_list "/limit|by|substr|mid|,|admi…...

LeetCode 题目 2545. 根据第 K 场考试的分数排序

在本篇文章中&#xff0c;我们将探讨如何根据第 K 场考试的分数对学生进行排序。这个问题是 LeetCode 上的一个中等难度问题&#xff0c;涉及到排序算法和自定义比较函数的使用。 问题描述 解题思路 理解问题 首先&#xff0c;我们需要理解问题的核心&#xff1a;根据第 K 场…...

算法随笔_12:最短无序子数组

上一篇: 算法随笔_11: 字符串的排列-CSDN博客 题目描述如下: 给你一个整数数组 nums &#xff0c;你需要找出一个 连续子数组 &#xff0c;如果对这个子数组进行升序排序&#xff0c;那么整个数组都会变为升序排序。请你找出符合题意的最短子数组&#xff0c;并输出它的长度。…...

计算机毕业设计PySpark+Hadoop+Hive机票预测 飞机票航班数据分析可视化大屏 航班预测系统 机票爬虫 飞机票推荐系统 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

Linux-C/C++--初探linux应用编程概念

对于大多数首次接触 Linux 应用编程的读者来说&#xff0c;可能对应用编程&#xff08;也可称为系统编程&#xff09;这个概念并不 太了解&#xff0c;所以在正式学习 Linux 应用编程之前&#xff0c;笔者有必要向大家介绍这些简单基本的概念&#xff0c;从整体上认识 到应用编…...

用sklearn运行分类模型,选择AUC最高的模型保存模型权重并绘制AUCROC曲线(以逻辑回归、随机森林、梯度提升、MLP为例)

诸神缄默不语-个人CSDN博文目录 文章目录 1. 导入包2. 初始化分类模型3. 训练、测试模型&#xff0c;绘图&#xff0c;保存指标 1. 导入包 from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier, GradientBoostingClass…...

动手学大数据-3社区开源实践

目录 数据库概览&#xff1a; MaxComput&#xff1a; HAWQ&#xff1a; Hologres&#xff1a; TiDB&#xff1a; Spark&#xff1a; ClickHouse&#xff1a; Apache Calcite 概览 Calcite RBO HepPlanner 优化规则&#xff08;Rule&#xff09; 内置有100优化规则 …...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...