不得不说的结构型模式-装饰器模式
目录
装饰器模式是什么
下面是装饰器模式的一个通用的类图:
以下是使用C++实现装饰器模式的示例代码:
下面是面试中关于桥接器模式的常见的问题:
下面是问题的答案:

装饰器模式是什么
装饰器模式是一种结构型设计模式,它允许在运行时动态地添加或修改对象的功能,而无需改变其原始类。在这个模式中,使用一个装饰器类来包装原始类,并且这个装饰器类和原始类具有相同的接口,这样就可以透明地将新的功能添加到原始对象中,而不需要修改原始对象的代码。
下面是装饰器模式的一个通用的类图:

以下是使用C++实现装饰器模式的示例代码:
#include <iostream>
using namespace std;// 基础组件类
class Component {
public:virtual void operation() = 0;
};// 具体组件类
class ConcreteComponent : public Component {
public:void operation() {cout << "ConcreteComponent operation." << endl;}
};// 装饰器基类
class Decorator : public Component {
protected:Component* component; // 指向被装饰对象的指针
public:Decorator(Component* comp) {component = comp;}void operation() {component->operation();}
};// 具体装饰器类A
class ConcreteDecoratorA : public Decorator {
public:ConcreteDecoratorA(Component* comp) : Decorator(comp) {}void operation() {Decorator::operation();cout << "ConcreteDecoratorA operation." << endl;}
};// 具体装饰器类B
class ConcreteDecoratorB : public Decorator {
public:ConcreteDecoratorB(Component* comp) : Decorator(comp) {}void operation() {Decorator::operation();cout << "ConcreteDecoratorB operation." << endl;}
};int main() {Component* comp = new ConcreteComponent();comp->operation();Component* dec1 = new ConcreteDecoratorA(comp);dec1->operation();Component* dec2 = new ConcreteDecoratorB(dec1);dec2->operation();delete comp;delete dec1;delete dec2;return 0;
}
在这个示例中,基础组件类Component定义了一个纯虚函数operation(),表示组件的操作。具体组件类ConcreteComponent实现了Component接口,并且实现了具体的操作。
装饰器基类Decorator也继承了Component接口,并且包含一个指向被装饰对象的指针component,它的实现中调用了被装饰对象的operation()方法。具体装饰器类ConcreteDecoratorA和ConcreteDecoratorB分别继承了Decorator,并且在调用被装饰对象的operation()方法之后,添加了自己的操作。
在main()函数中,首先创建了一个具体组件对象comp,然后使用具体装饰器类ConcreteDecoratorA和ConcreteDecoratorB对其进行装饰,并且调用了它们的operation()方法。在运行时,将看到输出如下:
ConcreteComponent operation.
ConcreteComponent operation.
ConcreteDecoratorA operation.
ConcreteDecoratorB operation.
在这个示例中,我们可以看到装饰器模式的实际应用。在不改变原始对象的情况下,可以通过添加一个或多个装饰器对象,来扩展原始对象的功能。这种方式非常灵活,因为可以在运行时动态地添加或删除装饰器对象,从而达到不同的效果。
下面是面试中关于装饰器模式的常见的问题:
-
你认为装饰器模式是什么?它的作用是什么?
-
装饰器模式与继承有什么区别?你能给出一个例子说明这两种方法的区别吗?
-
装饰器模式中的四个角色分别是什么?它们各自的作用是什么?
-
你是否在实际项目中使用过装饰器模式?可以分享一下你的经验吗?
-
装饰器模式的优缺点是什么?你认为在哪些场景下可以使用装饰器模式?
可以尝试自己思考一下,你的看法是什么,然后再看看答案,对比一下,看看有什么遗漏的地方=v=.
下面是问题的答案:
-
装饰器模式是一种结构型设计模式,它允许在运行时动态地添加或删除对象的行为,而不需要修改其源代码。它的作用是通过包装原始对象来扩展其功能,从而使代码更加灵活和易于维护。
-
装饰器模式通过包装原始对象来扩展其功能,而不需要修改其源代码。而继承则是通过创建子类来扩展父类的功能。装饰器模式具有更高的灵活性,可以在运行时动态添加或删除对象的行为,而继承则需要在编译时确定子类的行为。例如,如果要为一个类添加新的行为,使用继承需要创建一个新的子类来扩展父类的功能,而使用装饰器模式可以在运行时动态添加新的行为。
-
装饰器模式中的四个角色分别是:抽象组件(Component)、具体组件(ConcreteComponent)、抽象装饰器(Decorator)和具体装饰器(ConcreteDecorator)。其中,抽象组件定义了对象的基本行为,具体组件是实现抽象组件接口的类,抽象装饰器是所有装饰器的基类,具体装饰器是实现抽象装饰器接口的类。
-
在实际项目中,我曾经使用装饰器模式来扩展一个电商平台的订单处理系统。由于平台的订单类型非常多,而且不断有新的订单类型出现,为了保证代码的灵活性和可扩展性,我们使用装饰器模式来动态地添加或删除订单的行为,从而满足不同类型订单的需求。
-
装饰器模式的优点是可以在运行时动态地添加或删除对象的行为,从而使代码更加灵活和易于维护。它还遵循了开放封闭原则,即对扩展开放,对修改关闭。同时,装饰器模式还可以避免类爆炸问题,即避免创建大量的子类来扩展对象的行为。
然而,装饰器模式也有一些缺点。首先,它可能会导致过度使用装饰器,从而导致代码的复杂性和可读性降低。其次,由于装饰器模式增加了许多小类,因此它可能会导致代码库的大小增加。此外,装饰器模式还可能影响程序的性能,因为它需要在运行时动态地创建和组合对象。
总之,装饰器模式是一种非常有用的设计模式,可以帮助我们扩展对象的功能,从而使代码更加灵活和易于维护。它的应用场景包括但不限于:需要动态地添加或删除对象的行为,需要避免类爆炸问题,需要遵循开放封闭原则等。
欢迎大家讨论留言,批评指正,共同学习,共同进步!![]()
相关文章:
不得不说的结构型模式-装饰器模式
目录 装饰器模式是什么 下面是装饰器模式的一个通用的类图: 以下是使用C实现装饰器模式的示例代码: 下面是面试中关于桥接器模式的常见的问题: 下面是问题的答案: 装饰器模式是什么 装饰器模式是一种结构型设计模式ÿ…...
Flutter+YesAPI 快速构建零运维的APP
前言 移动互联网经过多年的发展,已经进入一个成熟的阶段,几乎每个公司都有自己的移动应用程序或移动网站。随着5G技术的不断发展,也带来了更高效的数据传输速度和更稳定的网络连接,这使得更多的应用程序和服务能够在互联网上运行&…...
使用Socks5代理保障HTTP传输的网络安全
一、引言 在互联网时代,网络安全越来越受到人们的关注,特别是在数据传输过程中,很容易出现信息泄露、窃听等安全问题。为了保障网络传输的安全性,我们可以使用代理服务器来进行传输,而Socks5代理是其中一种常用的代理…...
C语言入门篇——操作符篇
目录 1、操作符分类 2、操作符的属性 3、算术操作符 4、移位操作符 5、位操作符 6、赋值操作符 7、单目操作符 8、关系操作符 9、逻辑操作符 10、条件操作符 11、逗号操作符 12、下标引用、函数调用和结构成员 1、操作符分类 算术操作符(,-&…...
YOLOv7训练自己的数据集(txt文件,笔记)
目录 1.代码下载 2.数据集准备(.xml转.txt) (1)修改图像文件名 (2)图片和标签文件数量不对应,解决办法 (3).xml转.txt (4).txt文件随机划分出对应的训练…...
防止机械/移动硬盘休眠 - NoSleepHD
防止机械/移动硬盘休眠 - NoSleepHD 前言解决方案计算机硬盘移动硬盘 前言 机械硬盘休眠后唤醒需要一定时间,且频繁的启动和停止并不有利于硬盘的寿命,因此可根据自身需求防止机械硬盘休眠,下文以Win10系统为例介绍解决方案。 值得一提的是…...
(二)app自动化脚本录制回放
上一篇:(一)app自动化测试环境搭建(maciosairtest )_airtest环境搭建_要开朗的spookypop的博客-CSDN博客 注:后续都是用IOS设备来介绍自动化测试,安卓就不赘述了。 接上一篇,搭建好自动化测试环境后&#…...
STM32HAL库USART外设配置流程及库函数讲解
HAL库中USART外设配置流程及库函数讲解 一说到串口通信,及必须说一下aRS-232/485协议。232协议标准物理接口就是我们常用的DB9串口线 RS-232电平: 逻辑1:-15~-3 逻辑0: 3~15 COMS电平: 逻辑1:3.3 逻辑0&a…...
Qt 实现TCP通信和UDP通信
Qt 实现TCP通信和UDP通信 1、TCP通信 QT中实现TCP通信主要用到了以下类:QTcpServer、QTcpSocket、QHostAddress等; 使用QTcpServer来创建一个TCP服务器,在新的连接建立时,将新建立连接的socket添加到列表中,以便发送…...
完成近4亿元C轮融资+自研底盘域控,本土线控制动玩家“拼”了
显然,线控制动赛道已经进入白热化竞争阶段。 高工智能汽车研究院监测数据显示,2022年中国市场(不含进出口)乘用车前装搭载线控制动系统(One-Box,Two-Box)上险交付合计497.39万辆,同…...
【UE】一个简易的游戏计时器
效果 步骤 1. 打开“ThirdPersonGameMode” 创建两个整型变量,分别命名为“Seconds”、“Minutes” 在事件图表中添加如下节点,实现“Seconds”每秒加1 继续添加如下节点: 当秒数大于60时,就让分钟数1,然后将秒数重新…...
Leetcode力扣秋招刷题路-0455
从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结 455. 分发饼干 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i]&#x…...
一小时学会CSS (上)
1、CSS是什么? CSS (Cascading Style Sheets)层叠样式表,是一种来为结构化文档,例如HTML 、XML 添加字体,间距和颜色等样式的计算机语言,扩展名是.CSS 。 2、CSS语法规则 CSS写在哪里,CSS写在…...
DockerImage镜像版本说明
参考文章 1、https://medium.com/swlh/alpine-slim-stretch-buster-jessie-bullseye-bookworm-what-are-the-differences-in-docker-62171ed4531d 2、https://stackoverflow.com/questions/52083380/in-docker-image-names-what-is-the-difference-between-alpine-jessie-stret…...
ROS学习第三十三节——Arbotix使用
https://download.csdn.net/download/qq_45685327/87718484 1.介绍 通过 URDF 结合 rviz 可以创建并显示机器人模型,不过,当前实现的只是静态模型,如何控制模型的运动呢?在此,可以调用 Arbotix 实现此功能。 Arboti…...
ElasticSearch第十九讲 ES-best fields,most fields策略
multi-field多字段搜索 假设有个网站允许用户搜索博客的内容,以下面两篇博客内容文档为例: PUT /my_index/my_type/1 {"title": "Quick brown rabbits","body": "Brown rabbits are commonly seen." }PUT /my_index/my_type/2 {&…...
Netty详解,5分钟了解,面试不用慌
1. 概述 1.1 Netty 是什么? Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty 是一个异步的、基于事件驱动的网络应用框架,用…...
Logstash学习
一、Logstash基础 1、什么是Logstash logstash是一个数据抽取工具,将数据从一个地方转移到另一个地方。下载地址:https://www.elastic.co/cn/downloads/logstash logstash之所以功能强大和流行,还与其丰富的过滤器插件是分不开的ÿ…...
【流畅的Python学习笔记】2023.4.22
此栏目记录我学习《流畅的Python》一书的学习笔记,这是一个自用笔记,所以写的比较随意 元组 元组其实是对数据的记录:元组中的每个元素都存放了记录中一个字段的数据,外加这个字段的位置。简单试试元组的特性: char…...
使用django_celery_beat在admin后台配置计划任务
一、依赖包的安装 django中使用celery做异步任务和计划任务最头疼的点就是包之间版本兼容性问题,项目一启动花花报错,大概率都是版本问题。每次都会花很大时间在版本兼容性问题上。本例使用如下版本: Django3.2 celery5.2.7 django-celery-b…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
