设计模式10——装饰模式
写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。
装饰模式
是一种结构型模式。
目录
一、概述
1.1、主要的角色:
1.2、直观的理解装饰模式要干什么:
1.3、那么该如何思考呢?
1.4、我先给出描述对象之间关系的UML图:
1.5、什么是断点?
二、举例代码实现
2.1、对象之间的关系用UML图表示如下:
2.2、代码如下(建议你在本地试一下,加深印象):
一、概述
1、需要把所需的功能按正确的顺序串联起来进行控制;2、动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活;3、装饰模式是为已有的功能动态的添加更多功能的一种方式;4、主要是给一个核心类 动态的添加各种功能。
1.1、主要的角色:
主要的角色分两种,但从代码(或技术)实现的角度看(为了充分使用面向对象语言的3大特性封装、继承、多态,还另外需要抽象类或接口)可能有4个:
- 组件类:组件类的抽象类或接口 + 组件类的实现类
- 装饰类:装饰类的抽象类或接口 + 装饰类的实现类
1.2、直观的理解装饰模式要干什么:
举个简单例子,之前是只运行对象A,现在新加了对象B和对象C,当我们希望要运行的对象应该由对象A到对象B再到对象C,也就是希望对象运行之间有严格的顺序要求时,就可以尝试使用装饰模式。如我们希望达到的效果是这样的:

1.3、那么该如何思考呢?
可以从上可以看到,原先只有对象A,而对象B和对象C是后来加上的,且有严格的执行顺序,那么应用装饰模式后,我们可以认为:
- 对象A为组件类
- 对象B和对象C为装饰类,用来装饰对象A
除此之外,对于代码实现而言非常重要的东西是:
- 装饰类里的“断点”(这个词是我拍脑子想的,是为了帮助我们理解如何实现此模式而产生的,下面我会解释它是什么)。
1.4、我先给出描述对象之间关系的UML图:

1.5、什么是断点?
这是我从代码实现的角度提出的,所以要从代码的角度解释:
就拿上面的简单的举例来说,我们可以很明确地看到执行顺序是A-》B-》C,但实际代码实现上并非这样有前后顺序,而是你中有我、我中有你,解释图如下:

看懂上图我们就理解断点的意义了,同时也能发现装饰模式远比我们想象的更加灵活,不只是简单的A-》B-》C,就不再举例了。
需要说明的是,不同语言具体的实现方式略有不同,如:python的语法本身就支持装饰器,使用起来也更容易;而Java则需要创建装饰器父类,然后具体的装饰对象要继承父类,将调用父类的方法当做断点使用。但他们的共同点就是都有一个断点,这个断点可以用来插入别的类或对象的代码去运行。
二、举例代码实现
现有一个组件类和装饰类A、装饰类B,我们希望可以先运行组件类、再运行装饰类A、再运行装饰类B。
不再分析了,例子本身比较简单,而且上面概述当中也说的很清楚了。就直接给uml图和Java实现代码:
2.1、对象之间的关系用UML图表示如下:

2.2、代码如下(建议你在本地试一下,加深印象):
Java实现。
组件类的抽象类:
abstract class Component {public abstract void operation();
}
具体的组件类:
public class ConcreteComponent extends Component {@Overridepublic void operation() {System.out.println("具体组件对象的实际操作");}
}
装饰类的抽象类:
abstract class Decorator extends Component {protected Component component;public void setComponent(Component component) {this.component = component;}@Overridepublic void operation() {if (this.component != null) {component.operation();}}
}
装饰类A:
public class ConcreteDecoratorA extends Decorator {private String testA;@Overridepublic void operation() {super.operation(); //断点this.testA = "具体装饰对象A的独有操作";System.out.println(this.testA);}
}
装饰类B:
public class ConcreteDecoratorB extends Decorator {@Overridepublic void operation() {super.operation(); //断点this.testB();}private void testB() {System.out.println("具体装饰对象B的独有操作");}
}
主程序(发起请求的类):
public class Main {public static void main(String[] args) {ConcreteComponent component = new ConcreteComponent();ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA();ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB();concreteDecoratorA.setComponent(component);concreteDecoratorB.setComponent(concreteDecoratorA);concreteDecoratorB.operation();}
}
这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。
如果觉得本文还不错,就请点个赞给作者一点鼓励吧!如果有建议,也请评论指教和讨论!
相关文章:
设计模式10——装饰模式
写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。 装饰模式 是一种结构型模式。…...
如果返回的json 中有 ‘///’ 转换
// 将返回数据的三条/和替换空 rowData.Jsonobj rowData.Jsonobj .replace(/^\s*\/\/\/.*$/gm, //); // 将返回的替换成" 并且外面加个"" rowData.Jsonobj "${rowData.Jsonobj .replace(//g, ")}"; // 转换回来数据用两个 JSON.parse(JSON.par…...
JAVA学习-练习试用Java实现“多线程问题”
问题: 1.程序中需要开启两个线程(线程1和线程2) 2.线程1固定5秒钟执行一次 3.线程2固定10秒钟执行一次 4.开启程序如何做到线程1执行完成后再执行线程2并且在之后无论谁先执行都需等待对方执行完成后才可以开始执行 解答思路: 要实现线程 1 执行完成…...
SQOOP详细讲解
SQOOP安装及使用 SQOOP安装及使用SQOOP安装1、上传并解压2、修改文件夹名字3、修改配置文件4、修改环境变量5、添加MySQL连接驱动6、测试准备MySQL数据登录MySQL数据库创建student数据库切换数据库并导入数据另外一种导入数据的方式使用Navicat运行SQL文件导出MySQL数据库impo…...
【Unity入门】认识Unity编辑器
Unity 是一个广泛应用于游戏开发的强大引擎,从 1.0 版本开始到现在,其编辑器的基本框架一直保持稳定。其基于组件架构的设计,使得界面使用起来直观且高效。为了更好地理解 Unity 的界面,我们可以将其比喻为搭建一个舞台。以下是对…...
Spring控制重复请求
通过AOP拦截所有请求,控制在规定时间内请求次数。 1:添加maven <dependency><groupId>net.jodah</groupId><artifactId>expiringmap</artifactId><version>0.5.10</version> </dependency> 2&#x…...
AWS安全性身份和合规性之Key Management Service(KMS)
AWS Key Management Service(KMS)是一项用于创建和管理加密密钥的托管服务,可帮助客户保护其数据的安全性和机密性。 比如一家医疗保健公司需要在AWS上存储敏感的病人健康数据,需要对数据进行加密以确保数据的机密性。他们使用AW…...
esp32 固件备份 固件恢复
首先是固件备份,这个在产品的工程管理中还是相当重要的。由于工具链的更新(工具版本),以及板子或其上物料的变更(硬件版本),或者新的库的导入或原有库的删除,PCBA是分分钟有可能死给…...
linux开发之设备树四、设备树中断节点
中断节点 这里是由原厂的BSP工程师写的一部分 在CPU的外部有一个GIC控制器,外设会连接在GIC控制器上 设备树是对硬件进行描述的,所以设备树会对CPU进行描述,也要对GIC 控制器进行描述,这部分的代码由原厂的BSP工程师进行编写&…...
基于STM32实现智能楼宇对讲系统
目录 引言环境准备智能楼宇对讲系统基础代码示例:实现智能楼宇对讲系统 音频输入和输出按键控制显示屏和用户界面网络通信应用场景:楼宇安防与智能家居问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在STM32嵌入式系统中使用C语言实现智能…...
面试专区|【DevOps-46道DevOps高频题整理(附答案背诵版)】
简述什么是 DevOps工作流程 ? DevOps工作流程是一种将开发和运维团队紧密结合起来的方法,旨在实现软件开发和交付的高效性和可靠性。它强调自动化和持续集成,以便频繁地进行软件交付和部署。 DevOps工作流程通常包括以下阶段: …...
算法基础之台阶-Nim游戏
台阶-Nim游戏 核心思想:博弈论 可以看作第i阶台阶上有i个含有i个石子的堆这样所有台阶上一共n!个堆就变成了经典Nim优化:发现偶数阶台阶上2n堆异或 0 , 奇数阶台阶异或 原本石子数量 因此 当遍历到奇数阶时异或一下就行 #include <iostream>…...
VUE3注册指令的方法
指令注册只能全局指令和选项式页面指令,composition api没有页面指令 选项式页面指令 <template><div class"home"><h3>自定义指令</h3><div class"from"><el-input type"text" v-focus v-model"name&q…...
【Python】 Python 字典查询:‘has_key()‘ 方法与 ‘in‘ 关键字的比较
基本原理 在 Python 中,字典(dict)是一种非常常用的数据结构,用于存储键值对。字典的查询操作是编程中常见的任务之一。在 Python 2.x 版本中,has_key() 方法被用来检查字典中是否存在某个键。然而,在 Pyt…...
IDEA通过tomcat运行注意事项
配置run--》edit configurations 以下的A B部分要保持一致 A和B的路径要保持一致...
Unity Hub 添加模块报错 Validation Failed 的解决办法
提供两种方法,请自行选择其中一种。 在C:\Windows\System32\drivers\etc\hosts中添加下面的内容并保存后,完全关闭Unity Hub并重新打开,再次尝试下载刚刚失败的模块。 127.0.0.1 public-cdn.cloud.unity3d.com 127.0.0.1 public-cdn.cloud.…...
软件功能测试的类型和流程分享
在现代社会,软件已经成为人们生活中不可或缺的一部分,而在软件的开发过程中,功能测试是不可或缺的环节。软件功能测试指的是对软件系统的功能进行检查和验证,以确保软件在各种情况下能够正常运行,并且能够按照用户需求…...
【C语言】atoi函数的使用及模拟实现
atoi (ascii to integer),是把参数 str 所指向的字符串转换为一个整数(int类型)的库函数。 使用场景 引子: 有兴趣的朋友可以听我逐句翻译一下cpluscplus.com里的这段解释(要考六级了练一下): …...
Golang:使用bndr/gotabulate实现美观的打印表格数据
bndr/gotabulate 可以使用 Go 语言简单、美观的打印表格数据 文档 https://pkg.go.dev/github.com/bndr/gotabulatehttps://github.com/bndr/gotabulate 安装 go get github.com/bndr/gotabulate代码示例 package mainimport ("fmt""github.com/bndr/gotab…...
充电宝哪款好用?什么牌子充电宝耐用?充电宝选购要点总结
随着科技的飞速发展,充电宝已成为现代生活的必备之物。无论是日常通勤、旅行出差,还是在紧急情况下,充电宝都能为我们的电子设备提供可靠的电力支持。然而,面对市场上众多品牌和型号的充电宝,如何选择一款性价比高的充…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...
