C++二十三种设计模式之装饰模式

embedded/2025/1/8 17:08:26/

C++二十三种设计模式之装饰模式

  • 一、组成
  • 二、特点
  • 三、目的
  • 四、缺点
  • 五、示例代码

一、组成

抽象组件类:为具体组件类和抽象装饰器类提供共同的父类。
具体组件类:被具体装饰器类装饰的类。
抽象装饰器类:持有具体组件类的引用。继承抽象组件类,实现调用具体组件类接口。
具体装饰器类:实现调用抽象装饰器类接口。

二、特点

1、抽象装饰器类继承抽象组件类保证和被装饰对象有相同的接口。
2、具体装饰器类会先调用基类功能接口,再调用自己的功能接口,来保证在原来组件功能的基础上增加额外的功能。

三、目的

动态地给对象增加额外的功能。

四、缺点

1、性能开销问题,装饰链过长时,装饰器的间接调用会带来额外的性能开销。
2、复杂性问题,装饰链过长时,会让理解和调试变得困难。

五、示例代码

#include<iostream>
#include <vector>
#include <string>
#include <mutex>using namespace std;class Control;//抽象组件类
class Rectangle;//具体组件类
class Decorator;//抽象装饰器类
class VerScrollBar;//具体装饰器类
class BorderDec;//具体装饰器类class Control {
public:Control() {}Control(string name) : m_name(name) {};virtual ~Control() {};virtual void draw() = 0;protected:string m_name;
};class Rectangle : public Control {
public:Rectangle(string name) {m_name = name;};~Rectangle() {};void draw() override {cout << m_name << " draw Rectangle" << endl;};
};class Decorator : public Control {
public:Decorator(Control* tmpCtl, string name) : m_control(tmpCtl) {m_name = name;};void draw() override {m_control->draw();};
private:Control* m_control;
};class VerScrollBar : public Decorator {
public:VerScrollBar(Control* tmpCtl, string name) : Decorator(tmpCtl, name) {};~VerScrollBar() {};void draw() override {Decorator::draw();//调用基类的draw方法drawVerScrollBar();};
private:void drawVerScrollBar() {cout << m_name << " drawVerScrollBar" << endl;}
};class BorderDec : public Decorator {
public:BorderDec(Control* tmpCtl, string name) : Decorator(tmpCtl, name) {};~BorderDec() {};void draw() override {Decorator::draw();//调用基类的draw方法drawBorder();};
private:void drawBorder() {cout << m_name << " drawBorder" << endl;}
};int main() {Control* rec = new Rectangle("矩形");Decorator* border = new BorderDec(rec, "边框");Decorator* verScrollBar = new VerScrollBar(border, "垂直滚动条");verScrollBar->draw();
}

http://www.ppmy.cn/embedded/152337.html

相关文章

【Unity笔记】资源包导入后是洋红色(粉色)怎么办?

1.导入后发现是这样的 2.这个问题是渲染管道不匹配引起的。 导入的素材用的是 「通用渲染管线 Universal Render Pipeline, URP」&#xff0c;而项目里默认配置的是「内置渲染管线」&#xff0c;如图&#xff1a; 【知识补充】什么是渲染管线&#xff1f;&#xff1f;&#x…

SQL从入门到实战

学前须知 sqlzoo数据介绍 world nobel covid ge game、goal、eteam teacher、dept movie、casting、actor 基础语句 select&from SELECT from WORLD Tutorial - SQLZoo 基础查询select单列&多列&所有列&别名应用 例题一 SELECT name, continent, population …

李宏毅机器学习课程笔记02 | 机器学习任务攻略General Guide

第一步&#xff1a;分析loss on training data 先检查在训练数据上模型是否很好的学习 情况1&#xff1a;如果在训练集上&#xff0c;loss很大&#xff0c;说明在训练资料上没有训练好 可能性1&#xff1a;设置的模型太简单了&#xff0c;模型存在model bias模型偏差&#x…

Redis数据库笔记——ZSet的底层实现(跳表)

大家好&#xff0c;这里是Good Note&#xff0c;关注 公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍ZSet数据类型中跳表的底层实现&#xff0c;包括基本特点和常用操作。 文章目录 ZSet&#xff08;有序集合&#xff09;概述基本特点底层实现 Ski…

使用vue项目中,使用webpack模板和直接用vue.config来配置相关插件 区别是什么,具体有哪些提现呢

在 Vue 项目中&#xff0c;使用 Webpack 模板 和 vue.config.js 来配置相关插件的主要区别在于配置的复杂度、灵活性和易用性。以下是两者的详细对比&#xff1a; 1. Webpack 模板 Webpack 模板是 Vue CLI 早期版本&#xff08;如 Vue CLI 2.x&#xff09;中提供的项目初始化模…

网站运营数据pv、uv、ip

想要彻底弄清楚pv uv ip的区别&#xff0c;首先要知道三者的定义&#xff1a; IP(独立IP)的定义&#xff1a; 即Internet Protocol,指独立IP数。24小时内相同公网IP地址只被计算一次。 PV(访问量)的定义&#xff1a; 即Page View,即页面浏览量或点击量&#xff0c;用户每次刷…

(转)rabbitmq怎么保证消息不丢失?

RabbitMQ 可以通过以下多种机制来保证消息不丢失&#xff1a; 生产阶段 - 持久化队列和交换器&#xff1a; - 在声明队列和交换器时&#xff0c;将 durable 参数设置为 true &#xff0c;确保它们是持久化的。这样&#xff0c;即使 RabbitMQ 节点重新启动&#xff0c;队列和交…

【测试】持续集成CI/CD

近期更新完毕&#xff0c;建议关注收藏点赞&#xff5e; 目录 概括gitJenkinspostman集成jenkins代码集成jenkins 概括 CI/CD stands for Continuous Integration and Continuous Deployment 定义 团队成果持续集成到公共平台。一天可以集成1次or多次 本地代码管理 git 远程代…