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

设计模式8、装饰者模式 Decorator

解释说明:动态地给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案
抽象构件(Component):定义一个抽象接口以规范准备收附加责任的对象
具体构件(ConcreteComponent):实现抽象构件,通过装饰角色为其添加一些职责
抽象装饰类(Decorator):继承或实现抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能
具体装饰类(ConcreteDecorator):实现抽象装饰的相关方法,并给具体构件对象添加附加的责任
优点:
Decorator 模式与继承关系的目的都是要扩展对象的功能,但是 Decorator 可以提供比继承更多的灵活性。
通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。
缺点:
这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
装饰模式是针对抽象构建(Component)类型编程。但是,如果要针对具体构件(ConcreteComponent)编程,应该重新思考应用架构,以及装饰者是否合适。当然也可改变 Component 接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。
适用场景
需要扩展一个类的功能,或给一个类添加附加职责。
需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类
#pragma once
#include <string>
using namespace std;
// 所有饮料的基类
class IBeverage
{
public:virtual string Name() = 0;  // 名称virtual double Cost() = 0;  // 价钱
};
/********** 具体的饮料(咖啡)**********/
// 黑咖啡,属于混合咖啡
class HouseBlend : public IBeverage
{
public:string Name() {return "HouseBlend";}double Cost() {return 30.0;}
};
// 深度烘培咖啡豆
class DarkRoast : public IBeverage
{
public:string Name() {return "DarkRoast";}double Cost() {return 28.5;}
};#pragma once
#include "component.h"
// 调味品
class CondimentDecorator : public IBeverage
{
public:CondimentDecorator(IBeverage* beverage) : m_pBeverage(beverage) {}string Name() {return m_pBeverage->Name();}double Cost() {return m_pBeverage->Cost();}
protected:IBeverage* m_pBeverage;
};
/********** 具体的饮料(调味品)**********/
// 奶油
class Cream : public CondimentDecorator
{
public:Cream(IBeverage* beverage) : CondimentDecorator(beverage) {}string Name() {return m_pBeverage->Name() + " Cream";}double Cost() {return m_pBeverage->Cost() + 3.5;}
};
// 摩卡
class Mocha : public CondimentDecorator
{
public:Mocha(IBeverage* beverage) : CondimentDecorator(beverage) {}string Name() {return m_pBeverage->Name() + " Mocha";}double Cost() {return m_pBeverage->Cost() + 2.0;}
};
// 糖浆
class Syrup : public CondimentDecorator
{
public:Syrup(IBeverage* beverage) : CondimentDecorator(beverage) {}string Name() {return m_pBeverage->Name() + " Syrup";}double Cost() {return m_pBeverage->Cost() + 3.0;}
};#include "component.h"
#include "decorator.h"
#include <iostream>
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){delete(p); (p)=NULL;} }
#endif
int main()
{/********** 黑咖啡 **********/IBeverage* pHouseBlend = new HouseBlend();cout << pHouseBlend->Name() << " : " << pHouseBlend->Cost() << endl;// 黑咖啡 + 奶牛CondimentDecorator* pCream = new Cream(pHouseBlend);cout << pCream->Name() << " : " << pCream->Cost() << endl;// 黑咖啡 + 摩卡CondimentDecorator* pMocha = new Mocha(pHouseBlend);cout << pMocha->Name() << " : " << pMocha->Cost() << endl;// 黑咖啡 + 糖浆CondimentDecorator* pSyrup = new Syrup(pHouseBlend);cout << pSyrup->Name() << " : " << pSyrup->Cost() << endl;/********** 深度烘培咖啡豆 **********/IBeverage* pDarkRoast = new DarkRoast();cout << pDarkRoast->Name() << " : " << pDarkRoast->Cost() << endl;// 深度烘培咖啡豆 + 奶油CondimentDecorator* pCreamDR = new Cream(pDarkRoast);cout << pCreamDR->Name() << " : " << pCreamDR->Cost() << endl;// 深度烘培咖啡豆 + 奶油 + 摩卡CondimentDecorator* pCreamMocha = new Mocha(pCreamDR);cout << pCreamMocha->Name() << " : " << pCreamMocha->Cost() << endl;// 深度烘培咖啡豆 + 奶油 + 摩卡 + 糖浆CondimentDecorator* pCreamMochaSyrup = new Syrup(pCreamMocha);cout << pCreamMochaSyrup->Name() << " : " << pCreamMochaSyrup->Cost() <<  endl;SAFE_DELETE(pSyrup);SAFE_DELETE(pMocha);SAFE_DELETE(pCream);SAFE_DELETE(pHouseBlend);SAFE_DELETE(pCreamMochaSyrup);SAFE_DELETE(pCreamMocha);SAFE_DELETE(pCreamDR);SAFE_DELETE(pDarkRoast);getchar();return 0;
}

 

相关文章:

设计模式8、装饰者模式 Decorator

解释说明&#xff1a;动态地给一个对象增加一些额外的职责。就扩展功能而言&#xff0c;装饰模式提供了一种比使用子类更加灵活的替代方案 抽象构件&#xff08;Component&#xff09;&#xff1a;定义一个抽象接口以规范准备收附加责任的对象 具体构件&#xff08;ConcreteCom…...

抖音开放平台第三方代小程序开发,一整套流程

大家好&#xff0c;我是小悟 抖音小程序第三方平台开发着力于解决抖音生态体系内的小程序管理问题&#xff0c;一套模板&#xff0c;随处部署。能尽可能地减少服务商的开发成本&#xff0c;服务商只用开发一套小程序代码作为模板就可以快速批量的孵化出大量的商家小程序。 第…...

Flutter笔记:滚动之-无限滚动与动态加载的实现(GetX简单状态管理版)

Flutter笔记 无限滚动与动态加载的实现&#xff08;GeX简单状态管理版&#xff09; 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq…...

前端架构师之02_ES6_高级

1 类和继承 1.1 class类 JavaScript 语言中&#xff0c;生成实例对象的传统方法是通过构造函数。 // ES5 创建对象 // 创建一个类&#xff0c;用户名 密码 function User(name,pass){// 添加属性this.name name;this.pass pass; } // 用 原型 添加方法 User.prototype.sho…...

VScode多文件编译/调试配置

之前都是在Visual Studio写C/C&#xff0c;最近想换到VScode&#xff0c;折腾半天把launch.json和tasks.json配好了&#xff08;虽然不懂为什么&#xff0c;但确实能用了&#xff09;&#xff0c;在此做个记录。 参考资料&#xff1a;1&#xff0c;2&#xff0c;3 环境&#…...

K折交叉验证——cross_val_score函数使用说明

在机器学习中&#xff0c;许多算法中多个超参数&#xff0c;超参数的取值不同会导致结果差异很大&#xff0c;如何确定最优的超参数&#xff1f;此时就需要进行交叉验证的方法&#xff0c;sklearn给我们提供了相应的cross_val_score函数&#xff0c;可对数据集进行交叉验证划分…...

2023.09.30使用golang1.18编译Hel10-Web/Databasetools的windows版

#Go 1.21新增的 log/slog 完美解决了以上问题&#xff0c;并且带来了很多其他很实用的特性。 本次编译不使用log/slog 包 su - echo $GOPATH ;echo $GOROOT; cd /tmp; busybox wget --no-check-certificate https://go.dev/dl/go1.18.linux-amd64.tar.gz;\ which tar&&am…...

React简介

react作为前端主流框架之一&#xff0c;因其语法接近原生JavaScript语法而广受欢迎。其生态丰富&#xff0c;常用的就有react-router、react-redux等插件&#xff0c;还有与其匹配的UI组件库antd。而且其还有用于移动端开发的react-native库&#xff0c;因此&#xff0c;react值…...

链表经典面试题(一)

面试题 1.反转链表的题目2.反转链表的图文分析3.反转链表的代码实现 1.反转链表的题目 2.反转链表的图文分析 我们在实现反转链表的时候,是将后面的元素变前面&#xff0c;前面的元素变后面&#xff0c;那么我们是否可以理解为&#xff0c;用头插法的思想来完成反转链表呢&…...

体验亚马逊的 CodeWhisperer 感觉

CodeWhisperer 是亚马逊推出的辅助编程工具&#xff0c;在程序员写代码时&#xff0c;它能根据其内容生成多种代码建议。 CodeWhisperer 目前已支持近10几种语言&#xff0c;我是用 java 语言&#xff0c;用的开发工具是 idea&#xff0c;说一下我用的情况。 亚马逊云科技开发…...

6、行内元素和块元素

6、行内元素和块元素 一、块元素 无论内容多少&#xff0c;该元素独占一行 如p标签、标题标签&#xff08;h1-h6…&#xff09; 二、行内元素 内容撑开宽度、左右都是行内元素的可以排在一行 一些元素如果能够摆放在一行都可以用行内元素&#xff0c;但是如果需要换行就需…...

LeetCode 面试题 08.01. 三步问题

文章目录 一、题目二、Java 题解 一、题目 三步问题。有个小孩正在上楼梯&#xff0c;楼梯有n阶台阶&#xff0c;小孩一次可以上1阶、2阶或3阶。实现一种方法&#xff0c;计算小孩有多少种上楼梯的方式。结果可能很大&#xff0c;你需要对结果模1000000007。 示例1: 输入&…...

[CSCCTF 2019 Qual]FlaskLight 过滤 url_for globals 绕过globals过滤

目录 subprocess.Popen FILE warnings.catch_warnings site._Printer 这题很明显就是 SSTI了 源代码 我们试试看 {{7*7}} 然后我们就开始吧 原本我的想法是直接{{url_for.__globals__}} 但是回显是直接500 猜测过滤 我们正常来吧 {{"".__class__}} 查看当前…...

1分钟快速实现Redis数据对比

在上篇「Redis高效、安全的不停机数据迁移方案」的文章中&#xff0c;介绍了NineData在Redis迁移场景下的性能和优势。因为数据在主备、多云和多区域环境之间的迁移流动&#xff0c;难免会产生数据一致性的问题&#xff0c;而结构与数据不一致往往是导致故障的原因之一。所以&a…...

ASUS华硕天选4笔记本电脑FX507VV原厂Windows11系统

下载链接&#xff1a;https://pan.baidu.com/s/1W9tedHI3iFjaHju5eLkQ6g?pwd8dl2 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、华硕电脑管家、奥创控制中心等预装程序 由于时间关系,绝大部分资料没有上传&#xff0c;不是想要的型号&#xff0c;请联系客服获取。...

Vue3配置路由

文章目录 一、创建index.js二、main.js的配置三、在App.vue中引入 一、创建index.js 在src文件夹中创建router文件夹&#xff0c;并在其中创建index.js文件 //引入路由对象 import { createRouter,createWebHistory } from vue-router import PufMac from "../views/puf…...

力扣 -- 97. 交错字符串

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:bool isInterleave(string s1, string s2, string s3) {int ms1.size();int ns2.size();//先判断s1的长度s2的长度是否等于s3的长度&#xff0c;如果不等&#xff0c;则s1和s2不可能拼接成s3if(mn!s3.size…...

【剑指Offer】4.二维数组中的查找

题目 在一个二维数组array中&#xff08;每个一维数组的长度相同&#xff09;&#xff0c;每一行都按照从左到右递增的顺序排序&#xff0c;每一列都按照从上到下递增的顺序排序。请完成一个函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该…...

独立按键控制LED亮灭、独立按键控制LED状态、独立按键控制LED显示二进制、独立按键控制LED移位——“51单片机”

各位CSDN的uu们你们好呀&#xff0c;今天依旧是小雅兰的51单片机的内容&#xff0c;内容主要是&#xff1a;独立按键控制LED亮灭、独立按键控制LED状态、独立按键控制LED显示二进制、独立按键控制LED移位&#xff0c;下面&#xff0c;让我们进入51单片机的世界吧&#xff01;&a…...

chrome extensions mv3通过content scripts注入/获取原网站的window数据

开发插件的都知道插件的content scripts和top window只共享Dom不共享window和其他数据&#xff0c;如果想拿挂载在window的数据还有点难度&#xff0c;下面会通过事件的方式传递cs和top window之间的数据写一个例子 代码 manifest.json 这里只搞了2个js&#xff0c;content.…...

震坤行API接口聚合解析,实现根据ID取商品详情

震坤行是一个工业品服务平台&#xff0c;提供了API接口供开发者使用。要根据ID获取商品详情&#xff0c;您需要使用震坤行API接口并进行相应的请求。 以下是使用震坤行API接口根据ID获取商品详情的示例代码&#xff08;使用Python编写&#xff09;&#xff1a; import reques…...

mencpy和strcpy的区别?

今天刷题时遇到了这个问题&#xff0c;记录一下。 strcpy比较简单&#xff0c;就是拷贝字符串&#xff0c;遇到\0时结束拷贝。 memcpy用来做内存拷贝&#xff0c;可以拷贝任何数据类型的对象并指定拷贝数据的长度&#xff1a;char a[100],b[50]; memcpy(b, a, sizeof(b)); 总结…...

机器人过程自动化(RPA)入门 8. 异常处理、调试和日志记录

有时,自动化程序可能无法执行。为了处理此类情况,我们使用异常处理活动。在本章中,我们将从UiPath中可用的各种类型的异常处理方法、您可能遇到的异常以及如何处理它们开始。我们还将学习日志记录。本章涉及的一个重要主题是调试,以检查工作流是否正常工作,并更正任何错误…...

tomcat总结笔记

文章目录 Tomcat1、什么是tomcat?2、rpm安装jre环境3、源码安装jdk环境4、安装tomcat --源码安装5、相关目录文件webappsTomcat 配置文件目录介绍&#xff08;conf&#xff09;tomcat的相关管理命令在$prefix/bin目录下 实战1、&#xff1a;配置nginx动静分离实战2、配置基于t…...

中断向量控制器(NVIC)

1. 什么是中断 在处理器中&#xff0c;中断是一个过程&#xff0c;即CPU在正常执行程序的过程中&#xff0c;遇到外部/内部的紧急事件需要处理&#xff0c;暂时中止当前程序的执行&#xff0c;转而去为处理紧急的事件&#xff0c;待处理完毕后再返回被打断的程序处继续往下执行…...

QT配置FFmpeg出现错误原因

文章目录 QT配置ffmpeg出现&#xff1a; undefined reference to "avcodec_version"没有配置环境变量QT和FFmpeg的版本不对应直接添加FFmpeg的头文件没有在.pro文件添加路径 QT 程序异常退出没有在debug文件里面存放dll库 QT配置ffmpeg出现&#xff1a; undefined re…...

列出使用Typescript的一些优点?

使用Typescript有以下优点&#xff1a; 类型安全&#xff1a;Typescript是一种静态类型语言&#xff0c;它要求在编码阶段明确定义变量和函数的类型。这种类型安全可以减少在运行时出现错误的可能性&#xff0c;并提高代码的可读性和可维护性。代码可读性和可维护性&#xff1…...

如何做好测试?(四)集成测试(Integration Testing, IT)

1. 集成测试的详细介绍&#xff1a; 集成测试&#xff08;Integration Testing, IT&#xff09;&#xff0c;是一种软件测试方法&#xff0c;旨在验证不同组件、模块或子系统之间的交互和集成是否正常工作。它侧重于测试系统的组件之间的接口和数据传递&#xff0c;以确保它们…...

二叉树前序、中序、后序遍历(递归法、迭代法)

前序遍历&#xff1a;&#xff08;练习题&#xff09; 迭代法一&#xff1a; int TreeSize(struct TreeNode* root){return rootNULL?0:TreeSize(root->left)TreeSize(root->right)1; }int* preorderTraversal(struct TreeNode* root, int* returnSize){if(rootNULL){*…...

npm ,yarn 更换使用国内镜像源,淘宝源

背景 文章首发地址 在平时开发当中&#xff0c;我们经常会使用 Npm&#xff0c;yarn 来构建 web 项目。但是npm默认的源的服务器是在国外的&#xff0c;如果没有梯子的话。下载速度会特别慢。那有没有方法解决呢&#xff1f; 其实是有的&#xff0c;设置国内镜像即可&#x…...

php网站源码模板/代写软文费用全网天下实惠

1&#xff0c;JS中如何实现数字相加 2&#xff0c;js获取当前日期时间 转载于:https://www.cnblogs.com/robinunix/p/11011201.html...

济南城乡建设委员会网/汕头seo网站推广

HDC设备上下文是一种包含有关某个设备&#xff08;如显示器或打印机&#xff09;的绘制属性信息的 Windows 数据结构。所有绘制调用都通过设备上下文对象进行&#xff0c;这些对象封装了用于绘制线条、形状和文本的 Windows API。外文名HDC属 于MFC中的设备上下文句柄封 …...

郑州网站优化排名推广/网站建设平台有哪些

题目链接&#xff1a;51nod 1265 四点共面 四个点构成的三个向量a,b,c共面的充要条件是存在不全为零的实数x,y,z满足x*ay*bz*c0&#xff0c;然后想到线代了.. 其实就是三个向量的混合积为0&#xff1a;(a,b,c)(ab)c |ax ay az| |bx by bz| ax*by*czay*bz*cxbx*cy*az-az*by*c…...

哪个网站可以做问卷/百度关键词价格排行榜

下拉刷新上拉加载框架&#xff1a;PtrClassicFrameLayout 1、一个优雅的框架实现下拉刷新上拉加载&#xff0c;学习来源&#xff1a;点击打开链接 2、如何使用&#xff1a; 2.1、在项目中引入&#xff1a; compile com.shizhefei:MVCHelper-UltraRefresh:1.3.2compile in.s…...

wordpress css判断浏览器 分辨率 小于1024 90/前端seo是什么

前一阵写了一篇如何安装spacewalk,今这篇是如何将Kickstart与spacewalk and cobbler结合在一起。玩了玩这个类似红帽的satellite&#xff0c;蛮简单的。 1、创建一个发布&#xff1a; 如果存在多个linux发行版&#xff0c;则对每个发行版创建发布&#xff0c;以rhel6为例。当前…...

浙江网站建设抖音seo优化/app开发需要哪些技术

Oracle GoldenGate软件基于数据库日志结构变化&#xff0c;通过解析源端在线日志或归档日志获得数据增量&#xff0c; 再将这些变化传输并应用到目标数据库&#xff0c;从而实现源库和目标库的数据同步 卸载goldengate&#xff0c;需要停止gg相关的所有服务&#xff0c;删除gg所…...