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

不得不说的结构型模式-装饰器模式

目录

 装饰器模式是什么

下面是装饰器模式的一个通用的类图:

以下是使用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()方法。具体装饰器类ConcreteDecoratorAConcreteDecoratorB分别继承了Decorator,并且在调用被装饰对象的operation()方法之后,添加了自己的操作。

main()函数中,首先创建了一个具体组件对象comp,然后使用具体装饰器类ConcreteDecoratorAConcreteDecoratorB对其进行装饰,并且调用了它们的operation()方法。在运行时,将看到输出如下:

ConcreteComponent operation.
ConcreteComponent operation.
ConcreteDecoratorA operation.
ConcreteDecoratorB operation.

在这个示例中,我们可以看到装饰器模式的实际应用。在不改变原始对象的情况下,可以通过添加一个或多个装饰器对象,来扩展原始对象的功能。这种方式非常灵活,因为可以在运行时动态地添加或删除装饰器对象,从而达到不同的效果。

下面是面试中关于装饰器模式的常见的问题:

  1. 你认为装饰器模式是什么?它的作用是什么?

  2. 装饰器模式与继承有什么区别?你能给出一个例子说明这两种方法的区别吗?

  3. 装饰器模式中的四个角色分别是什么?它们各自的作用是什么?

  4. 你是否在实际项目中使用过装饰器模式?可以分享一下你的经验吗?

  5. 装饰器模式的优缺点是什么?你认为在哪些场景下可以使用装饰器模式?

可以尝试自己思考一下,你的看法是什么,然后再看看答案,对比一下,看看有什么遗漏的地方=v=.

下面是问题的答案:

  1. 装饰器模式是一种结构型设计模式,它允许在运行时动态地添加或删除对象的行为,而不需要修改其源代码。它的作用是通过包装原始对象来扩展其功能,从而使代码更加灵活和易于维护。

  2. 装饰器模式通过包装原始对象来扩展其功能,而不需要修改其源代码。而继承则是通过创建子类来扩展父类的功能。装饰器模式具有更高的灵活性,可以在运行时动态添加或删除对象的行为,而继承则需要在编译时确定子类的行为。例如,如果要为一个类添加新的行为,使用继承需要创建一个新的子类来扩展父类的功能,而使用装饰器模式可以在运行时动态添加新的行为。

  3. 装饰器模式中的四个角色分别是:抽象组件(Component)、具体组件(ConcreteComponent)、抽象装饰器(Decorator)和具体装饰器(ConcreteDecorator)。其中,抽象组件定义了对象的基本行为,具体组件是实现抽象组件接口的类,抽象装饰器是所有装饰器的基类,具体装饰器是实现抽象装饰器接口的类。

  4. 在实际项目中,我曾经使用装饰器模式来扩展一个电商平台的订单处理系统。由于平台的订单类型非常多,而且不断有新的订单类型出现,为了保证代码的灵活性和可扩展性,我们使用装饰器模式来动态地添加或删除订单的行为,从而满足不同类型订单的需求。

  5. 装饰器模式的优点是可以在运行时动态地添加或删除对象的行为,从而使代码更加灵活和易于维护。它还遵循了开放封闭原则,即对扩展开放,对修改关闭。同时,装饰器模式还可以避免类爆炸问题,即避免创建大量的子类来扩展对象的行为。

    然而,装饰器模式也有一些缺点。首先,它可能会导致过度使用装饰器,从而导致代码的复杂性和可读性降低。其次,由于装饰器模式增加了许多小类,因此它可能会导致代码库的大小增加。此外,装饰器模式还可能影响程序的性能,因为它需要在运行时动态地创建和组合对象。

    总之,装饰器模式是一种非常有用的设计模式,可以帮助我们扩展对象的功能,从而使代码更加灵活和易于维护。它的应用场景包括但不限于:需要动态地添加或删除对象的行为,需要避免类爆炸问题,需要遵循开放封闭原则等。

欢迎大家讨论留言,批评指正,共同学习,共同进步!

相关文章:

不得不说的结构型模式-装饰器模式

目录 装饰器模式是什么 下面是装饰器模式的一个通用的类图&#xff1a; 以下是使用C实现装饰器模式的示例代码&#xff1a; 下面是面试中关于桥接器模式的常见的问题&#xff1a; 下面是问题的答案&#xff1a; 装饰器模式是什么 装饰器模式是一种结构型设计模式&#xff…...

Flutter+YesAPI 快速构建零运维的APP

前言 移动互联网经过多年的发展&#xff0c;已经进入一个成熟的阶段&#xff0c;几乎每个公司都有自己的移动应用程序或移动网站。随着5G技术的不断发展&#xff0c;也带来了更高效的数据传输速度和更稳定的网络连接&#xff0c;这使得更多的应用程序和服务能够在互联网上运行&…...

使用Socks5代理保障HTTP传输的网络安全

一、引言 在互联网时代&#xff0c;网络安全越来越受到人们的关注&#xff0c;特别是在数据传输过程中&#xff0c;很容易出现信息泄露、窃听等安全问题。为了保障网络传输的安全性&#xff0c;我们可以使用代理服务器来进行传输&#xff0c;而Socks5代理是其中一种常用的代理…...

C语言入门篇——操作符篇

目录 1、操作符分类 2、操作符的属性 3、算术操作符 4、移位操作符 5、位操作符 6、赋值操作符 7、单目操作符 8、关系操作符 9、逻辑操作符 10、条件操作符 11、逗号操作符 12、下标引用、函数调用和结构成员 1、操作符分类 算术操作符&#xff08;&#xff0c;-&…...

YOLOv7训练自己的数据集(txt文件,笔记)

目录 1.代码下载 2.数据集准备&#xff08;.xml转.txt) &#xff08;1&#xff09;修改图像文件名 &#xff08;2&#xff09;图片和标签文件数量不对应&#xff0c;解决办法 &#xff08;3&#xff09;.xml转.txt &#xff08;4&#xff09;.txt文件随机划分出对应的训练…...

防止机械/移动硬盘休眠 - NoSleepHD

防止机械/移动硬盘休眠 - NoSleepHD 前言解决方案计算机硬盘移动硬盘 前言 机械硬盘休眠后唤醒需要一定时间&#xff0c;且频繁的启动和停止并不有利于硬盘的寿命&#xff0c;因此可根据自身需求防止机械硬盘休眠&#xff0c;下文以Win10系统为例介绍解决方案。 值得一提的是…...

(二)app自动化脚本录制回放

上一篇&#xff1a;(一)app自动化测试环境搭建&#xff08;maciosairtest &#xff09;_airtest环境搭建_要开朗的spookypop的博客-CSDN博客 注&#xff1a;后续都是用IOS设备来介绍自动化测试&#xff0c;安卓就不赘述了。 接上一篇&#xff0c;搭建好自动化测试环境后&#…...

STM32HAL库USART外设配置流程及库函数讲解

HAL库中USART外设配置流程及库函数讲解 一说到串口通信&#xff0c;及必须说一下aRS-232/485协议。232协议标准物理接口就是我们常用的DB9串口线 RS-232电平&#xff1a; 逻辑1&#xff1a;-15~-3 逻辑0&#xff1a; 3~15 COMS电平&#xff1a; 逻辑1&#xff1a;3.3 逻辑0&a…...

Qt 实现TCP通信和UDP通信

Qt 实现TCP通信和UDP通信 1、TCP通信 QT中实现TCP通信主要用到了以下类&#xff1a;QTcpServer、QTcpSocket、QHostAddress等&#xff1b; 使用QTcpServer来创建一个TCP服务器&#xff0c;在新的连接建立时&#xff0c;将新建立连接的socket添加到列表中&#xff0c;以便发送…...

完成近4亿元C轮融资+自研底盘域控,本土线控制动玩家“拼”了

显然&#xff0c;线控制动赛道已经进入白热化竞争阶段。 高工智能汽车研究院监测数据显示&#xff0c;2022年中国市场&#xff08;不含进出口&#xff09;乘用车前装搭载线控制动系统&#xff08;One-Box&#xff0c;Two-Box&#xff09;上险交付合计497.39万辆&#xff0c;同…...

【UE】一个简易的游戏计时器

效果 步骤 1. 打开“ThirdPersonGameMode” 创建两个整型变量&#xff0c;分别命名为“Seconds”、“Minutes” 在事件图表中添加如下节点&#xff0c;实现“Seconds”每秒加1 继续添加如下节点&#xff1a; 当秒数大于60时&#xff0c;就让分钟数1&#xff0c;然后将秒数重新…...

Leetcode力扣秋招刷题路-0455

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 455. 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#x…...

一小时学会CSS (上)

1、CSS是什么&#xff1f; CSS &#xff08;Cascading Style Sheets&#xff09;层叠样式表&#xff0c;是一种来为结构化文档&#xff0c;例如HTML 、XML 添加字体&#xff0c;间距和颜色等样式的计算机语言,扩展名是.CSS 。 2、CSS语法规则 CSS写在哪里&#xff0c;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 可以创建并显示机器人模型&#xff0c;不过&#xff0c;当前实现的只是静态模型&#xff0c;如何控制模型的运动呢&#xff1f;在此&#xff0c;可以调用 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 是什么&#xff1f; Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty 是一个异步的、基于事件驱动的网络应用框架&#xff0c;用…...

Logstash学习

一、Logstash基础 1、什么是Logstash logstash是一个数据抽取工具&#xff0c;将数据从一个地方转移到另一个地方。下载地址&#xff1a;https://www.elastic.co/cn/downloads/logstash logstash之所以功能强大和流行&#xff0c;还与其丰富的过滤器插件是分不开的&#xff…...

【流畅的Python学习笔记】2023.4.22

此栏目记录我学习《流畅的Python》一书的学习笔记&#xff0c;这是一个自用笔记&#xff0c;所以写的比较随意 元组 元组其实是对数据的记录&#xff1a;元组中的每个元素都存放了记录中一个字段的数据&#xff0c;外加这个字段的位置。简单试试元组的特性&#xff1a; char…...

使用django_celery_beat在admin后台配置计划任务

一、依赖包的安装 django中使用celery做异步任务和计划任务最头疼的点就是包之间版本兼容性问题&#xff0c;项目一启动花花报错&#xff0c;大概率都是版本问题。每次都会花很大时间在版本兼容性问题上。本例使用如下版本&#xff1a; Django3.2 celery5.2.7 django-celery-b…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...