不得不说的结构型模式-装饰器模式
目录
装饰器模式是什么
下面是装饰器模式的一个通用的类图:
以下是使用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…...
Apollo6.0 Lattice算法实战解析——从轨迹组合到最优路径生成
1. Lattice算法在Apollo6.0中的核心作用 Lattice算法是Apollo自动驾驶系统中的关键路径规划模块,它负责将横向和纵向轨迹进行智能组合,最终生成安全、舒适且符合交通规则的最优行驶路径。这个算法就像一位经验丰富的导航员,不仅要考虑车辆当前…...
RVC变声器全场景解决方案:6大核心问题的系统解决策略
RVC变声器全场景解决方案:6大核心问题的系统解决策略 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-Voice-Conversi…...
别再只用L2损失了!手把手教你用PyTorch实现MS-SSIM+L1混合损失,图像修复效果大提升
超越L1/L2:用MS-SSIM混合损失打造专业级图像修复模型 当你在深夜调试一个图像超分辨率模型时,屏幕上的结果让你皱起了眉头——那些应该清晰锐利的边缘却像被水浸湿的水彩画一样模糊不清,而平坦的天空区域则布满了令人不快的颗粒状伪影。这可能…...
comsol燃料电池堆冷却:模型对聚合物电解质膜 (PEM) 燃料电池堆的热管理进行建模 对电...
comsol燃料电池堆冷却:模型对聚合物电解质膜 (PEM) 燃料电池堆的热管理进行建模 对电池堆的所有电池单元来说,以相似的温度曲线进行操作非常重要,因为非均匀的温度分布可能会导致非均匀的水蒸气冷凝,以及电池单元之间出现较大的性…...
别再傻傻分不清了!LDO和DC-DC到底怎么选?从效率、温升到选型实战一次讲透
LDO与DC-DC终极选型指南:从理论到实战的完整决策框架 在硬件设计领域,电源方案的选择往往决定了整个系统的稳定性与能效表现。面对LDO(低压差线性稳压器)和DC-DC(直流-直流转换器)这两大主流方案࿰…...
javaweb驾校考试车辆预约系统
目录同行可拿货,招校园代理 ,本人源头供货商功能模块划分预约功能设计考试管理模块系统辅助功能技术实现参考项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商 功能模块划分 用户管理模块…...
javaweb蔚来新能源汽车对比推荐平台设计与实现
目录同行可拿货,招校园代理 ,本人源头供货商功能模块设计技术实现方案数据安全措施扩展功能设计项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商 功能模块设计 用户管理模块 实现用户注…...
28GHz毫米波滤波器设计实战:用SynMatrix快速搞定SIW带通滤波器(附完整参数)
28GHz毫米波滤波器设计实战:SynMatrix工具链的高效应用指南 在毫米波频段,滤波器设计一直是射频工程师面临的重大挑战之一。尤其是当工作频率上升到28GHz甚至更高时,传统设计方法往往陷入反复迭代的泥潭,耗费大量时间在仿真优化与…...
单片机案例:单位数码管显示0,7和轮转显示0—9
文章目录1.单位数码管显示0效果图代码2.单位数码管显示7效果图代码3.单位数码管轮转显示0—9效果图代码1.单位数码管显示0 效果图 代码 #include <reg52.h>#define uchar unsigned char #define uint unsigned int// 定义锁存器控制引脚 sbit LE P2^7; // 74HC573的锁…...
腾讯 CodeBuddy 全形态解析:IDE、CLI 与插件如何重塑 AI 编程体验
1. CodeBuddy 三形态全景解析:从终端到桌面的AI编程革命 第一次用CodeBuddy的CLI工具时,我在终端里输入"帮我写个Python爬虫抓取天气数据",三秒钟后看着自动生成的完整代码,手里的咖啡差点洒在键盘上。这就是腾讯CodeB…...
