装饰器模式(C++)

定义

动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码&减少子类个数)。
一《设计模式》 GoF

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

使用场景

  • 在某些情况下我们可能会“过度地使用继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。
  • 如何使“对象功能的扩展"能够根据需要来动态地实现?同时避免“扩展功能的增多"带来的子类膨胀问题?从而使得任何“功能扩展变化"所导致的影响将为最低?

结构

在这里插入图片描述

代码示例

//Decorator.h
/****************************************************/
#ifndef DECORATOR_H
#define DECORATOR_H
#include<iostream>
using namespace std;//创建一个形状的接口
class shape
{
public:shape() {};virtual ~shape() {};virtual void draw()=0;
};//创建圆形circle类继承形状基类接口
class circle :public shape
{
public:circle(){};~circle(){};void draw(){cout << "draw circle" << endl;}
};//创建一个三角形rectangle类继承形状shape基类
class rectangle :public shape
{
public:rectangle(){};~rectangle(){};void draw(){cout << "draw rectangle" << endl;}
};//创建一个形状装饰器ShapeDecorator类继承形状shape基类
class ShapeDecorator:public shape
{
public:ShapeDecorator(shape *td){decoratedshape = td;}virtual ~ShapeDecorator(){};void draw(){decoratedshape->draw();}
protected:shape *decoratedshape;
};//扩展ShapeDecorator为RedShapeDecorator
class RedShapeDecorator : public ShapeDecorator
{
public:RedShapeDecorator(shape *tf):ShapeDecorator(tf){}~RedShapeDecorator(){};void draw(){decoratedshape->draw();setRedBorder(decoratedshape);}
private://设置边框颜色void setRedBorder(shape *tg){cout << "Border Color:Red" << endl;}
};#endif
//test.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Decorator.h"int main()
{shape *redCircle = (shape*)new RedShapeDecorator(new circle());shape *redRectangle = (shape*)new RedShapeDecorator(new rectangle());redCircle->draw();redRectangle->draw();delete redCircle;delete redRectangle;return 0;
}

运行结果
在这里插入图片描述

要点总结

  • 通过采用组合而非继承的手法,Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的“灵活性差”和“多子类衍生问题”。
  • Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。
  • Decorator模式的目的并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”一是为“装饰”的含义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/77887.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习环境】安装anaconda、tensorflow、pycharm

目录 1.安装anaconda 2.安装tensorflow-gpu 3.安装pycharm 4.VNC操作 5.安装Pytorch PS: linux下常见的操作&#xff1a; 1.Linux下强制关闭程序&#xff1a; 2.导出环境 2.1.pip导出 2.2.conda导出 2.3.其他 3.windows下的环境安装 & pycharm远程配置 4.bash…

PostgreSQL Patroni_exporter 监控 patroni高可用工具

Patroni是Cybertec公司基于python语言开发的&#xff0c;可用于使用流复制来创建&#xff0c;管理&#xff0c;维护和监视高可用性PostgreSQL集群设置的工具。 目前&#xff0c;PatroniEtcd 是最为推荐的PostgreSQL数据库高可用方案之一。 PostgreSQL有postgres_exporter监控采…

人工智能学习07--pytorch23--目标检测:Deformable-DETR训练自己的数据集

参考 https://blog.csdn.net/qq_44808827/article/details/125326909https://blog.csdn.net/dystsp/article/details/125949720?utm_mediumdistribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-125949720-blog-125326909.235^v38^pc_releva…

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(18)-Fiddler如何接口测试,妈妈再也不担心我不会接口测试了

1.简介 Fiddler最大的优势在于抓包&#xff0c;我们大部分使用的功能也在抓包的功能上&#xff0c;fiddler做接口测试也是非常方便的。 领导或者开发给你安排接口测试的工作任务&#xff0c;但是没有给你接口文档&#xff08;由于开发周期没有时间出接口文档&#xff09;&…

ProgressBar基本使用

作用&#xff1a;进度条&#xff0c;用于展示某个任务的完成情况&#xff0c; 常用属性&#xff1a; 设定进度条的最大、最小值、自增步长 常用事件&#xff1a; 后台代码&#xff1a; private void progressBar1_Click(object sender, EventArgs e){Thread t;//使用线程执行…

TabR:检索增强能否让深度学习在表格数据上超过梯度增强模型?

这是一篇7月新发布的论文&#xff0c;他提出了使用自然语言处理的检索增强Retrieval Augmented技术&#xff0c;目的是让深度学习在表格数据上超过梯度增强模型。 检索增强一直是NLP中研究的一个方向&#xff0c;但是引入了检索增强的表格深度学习模型在当前实现与非基于检索的…

uniapp:图片验证码检验问题处理

图形验证码功能实现 uniapp&#xff1a;解决图形验证码问题及利用arraybuffer二进制转base64格式图片&#xff08;后端传的图片数据形式&#xff1a;x00\x10JFIF\x00\x01\x02\x00…&#xff09;_❆VE❆的博客-CSDN博客 UI稿&#xff1a; 需求&#xff1a;向后端请求验证码图片&…

03 制作Ubuntu启动盘

1 软碟通 我是用软碟通制作启动盘。安装软碟通时一定要把虚拟光驱给勾选上&#xff0c;其余两个可以看你心情。 2 镜像文件 我使用清华镜像网站找到的Ubuntu镜像文件。 Index of /ubuntu-releases/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 请自己选择镜像…

IOS看书最终选择|源阅读转换|开源阅读|IOS自签

环境&#xff1a;IOS想使用 换源阅读 问题&#xff1a;换新手机&#xff0c;源阅读下架后&#xff0c;没有好的APP阅读小说 解决办法&#xff1a;自签APP 转换源仓库书源 最终预览 &#xff1a;https://rc.real9.cn/ 背景&#xff1a;自从我换了新iPhone手机&#xff0c;就无法…

C# Blazor 学习笔记(10):依赖注入

文章目录 前言Blazor 依赖注入依赖注入用于解决什么问题&#xff1f;依赖注入的生命周期。测试代码 总结补充日期2023年8月4日 前言 Blazor 具有前后端不分离模式&#xff0c;但是如何直接调用需要一定的设置 Blazor 依赖注入 依赖注入在spring里面很常见&#xff0c;毕竟.N…

Gof23设计模式之组合模式

1.定义 ​组合模式又名部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次。这种类型的设计模式属于结构型模式&#xff0c;它创建了对象组的树形结构。 2.结构 组合模式主要包含三种…

ChatGPT-4.0:你准备好了吗?

3202年了&#xff0c;你还在用ChatGPT 3.5吗&#xff1f; 来感受一下ChatGPT 4.0的魅力吧 文末附升级链接 1、颠倒黑白&#xff1f; 2、解读幽默&#xff1f; 3、小镇做题家&#xff1f; 如何白嫖&#xff1f; 最后 1、科技的发展加快了知识更新的速度&#xff0c;唯有终身…

(四)Node.js - npm与包

1. 什么是包 Node.js中的第三方模块又叫做包。 不同于Node.js中的内置模块与自定义模块&#xff0c;包是由第三方个人或团队开发出来的&#xff0c;免费供所有人使用。 由于Node.js的内置模块进提供了一些底层的API&#xff0c;导致在基于内置模块进行项目开发时&#xff0c…

第五届太原理工大学新生赛(决赛)题解

题解&#xff09; <font colorred>第五届太原理工大学新生赛&#xff08;决赛&#xff09;:star:A.810975:star2:<font colorgreen>题意:cherries:<font colorred>解决思路:pear:代码 :star:<font colorpink>B.hammer玩游戏:star2:<font colorgreen…

服务器返回 413 Request Entity Too Large

问题 上传一个大于1.5M的文件时&#xff0c;报错&#xff1a;413 Request Entity Too Large 使用的配置 1、用的是docker环境&#xff0c;还有一层代理&#xff0c;代理用的镜像是&#xff1a;jwilder/nginx-proxy 2、docker里是有php和nginx 确认配置 docker里的php和ngi…

docker部署jenkins且jenkins中使用docker去部署项目

docker部署jenkins且jenkins中使用docker去部署项目 1、确定版本 2.346.1是最后一个支持jdk8的 2、编写docker-compose.yml并执行 在这个目录中新增data文件夹&#xff0c;注意data是用来跟docker中的文件进行映射的 docker-compose.yml version: "3.1" service…

【基础类】—三栏页面布局的方案和优缺点

一、假设高度已知&#xff0c;中间宽度自适应&#xff0c;三栏&#xff08;列&#xff09;布局的方案有哪些&#xff1f; float浮动、absolute绝对定位、flex弹性盒子、table表格布局、grid网格布局 浮动 float <style>* {margin: 0;padding: 0;}.container {width: 1…

opencv的Mask操作,选择图片中感兴趣的区域

最近做目标检测任务的时候&#xff0c;需要对固定区域的内容进行检测&#xff0c;要用到opencv的mask操作&#xff0c;选择图片固定的区域 代码 import cv2 import numpy as npimg cv2.imread(data/images/smoking.png)# 弹出一个框 让你选择ROI | x,y是左上角的坐标 x,y,w,…

【iOS】锁

线程安全 当一个线程访问数据的时候&#xff0c;其他的线程不能对其进行访问&#xff0c;直到该线程访问完毕。简单来讲就是在同一时刻&#xff0c;对同一个数据操作的线程只有一个。而线程不安全&#xff0c;则是在同一时刻可以有多个线程对该数据进行访问&#xff0c;从而得…

无涯教程-Perl - foreach 语句函数

foreach 循环遍历列表值&#xff0c;并将控制变量(var)依次设置为列表的每个元素- foreach - 语法 Perl编程语言中的 foreach 循环的语法是- foreach var (list) { ... } foreach - 流程图 foreach - 示例 #!/usr/local/bin/perllist(2, 20, 30, 40, 50);# foreach loop ex…