【C++】—— 装饰器模式

目录

(一)什么是装饰器模式

(二)为什么要使用装饰器模式

(三)装饰器模式的实现步奏

 (四)代码示例

(五)装饰器模式优缺点


(一)什么是装饰器模式

装饰模式(Decorator Pattern),也被称为包装模式,是一种通过对客户端透明的方式来扩展对象功能的设计模式,它提供了一种替代继承关系的方案。装饰模式通过将要添加的附加功能放在独立的类中,并让这个类包含要装饰的对象,实现了在运行时动态地给对象添加功能的能力。

在装饰模式中,抽象构件定义了对象的接口,具体构件是被装饰的对象,装饰者持有一个构件对象的引用,并定义与抽象构件一致的接口。装饰者可以在调用构建对象的方法前后添加额外的行为,从而扩展对象的功能。

通过使用装饰模式,我们可以灵活地在运行时动态地给对象添加功能,而无需改变原有类的结构。客户端可以按照需要选择、按顺序使用不同的装饰者来包装对象,从而达到组合各种功能的目的。这种方式实现了功能的扩展和复用,同时也避免了使用继承带来的静态特性和多个子类的维护问题。


(二)为什么要使用装饰器模式

  1. 装饰模式可以动态的给一个对象添加一 些额外的职责。
  2. 就增加功能来说,此模式比生成子类更为灵活,通过子类继承的方式,但是如果后续继续增加功能的话,便要继续继承现有的类,如此就会使继承的层次越来越深,不利与代码的维护和可读性。
  3. 故最好的方式便是通过装饰者模式来完成。

(三)装饰器模式的实现步奏

  • 提供一个抽象组件类:抽象被装饰者的行为
  • 提供一个或多个具体组件类:被装饰者的行为具体实现
  • 提供一个抽象装饰器类:抽象组件指针与抽象组件一致接口
  • 提供一个具体的装饰器类:为具体组件附加责任


 (四)代码示例

场景

  • 对于一些职场人士在出席一些重要场合的时候,大部分都是西装革履的。因此,我在这里就模拟男士穿衣的场景

首先,定义一个抽象基类Boy代表男生;

class Boy {
public:virtual void wearClothes() = 0;
};

接下来,创建具体的男生类;

class ConcreteBoy : public Boy {
public:void wearClothes() override {cout << "首先穿上打底衫" << endl;}
};

 然后,定义装饰器基类;

class Decorator : public Boy {
protected:Boy* boy;
public:Decorator(Boy* b) : boy(b) {}virtual void wearClothes() override {if (boy != nullptr) {boy->wearClothes();}}
};

接着,创建具体的装饰器类;

//穿西装
class JacketDecorator : public Decorator {
public:JacketDecorator(Boy* b) : Decorator(b) {}void wearClothes() override {Decorator::wearClothes();cout << "紧接着穿上西服" << endl;}
};//打领带
class TieDecorator : public Decorator {
public:TieDecorator(Boy* b) : Decorator(b) {}void wearClothes() override {Decorator::wearClothes();cout << "最后再打领带" << endl;}
};

最后,在主函数中使用这些类来展示男生穿衣服的场景;

int main() {Boy* boy = new TieDecorator(new JacketDecorator(new ConcreteBoy()));boy ->wearClothes();delete boy ;return 0;
}

(五)装饰器模式优缺点

优点

  1. 灵活性:装饰器模式允许动态地给对象添加功能,而且可以根据需要多次进行装饰,从而实现各种组合方式,使得功能扩展变得非常灵活。
  2. 开闭原则:装饰器模式符合开闭原则,可以在不修改现有代码的情况下,增加新的功能。

缺点

  1. 复杂性:装饰器模式引入了许多小的对象和类,可能会导致系统中对象数量的增加,从而增加系统的复杂性。
  2. 容易出错:由于装饰器模式允许灵活地组合对象,因此在设计时需要特别小心,以避免出现过度复杂或混乱的装饰器组合,导致难以理解和维护的问题。

总体来说,装饰器模式是一种非常灵活的设计模式,能够有效地扩展对象的功能,同时也需要在设计时注意控制复杂性,避免出现过度装饰的情况。

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

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

相关文章

Codeforces Round 935 (Div. 3)A~E

A. Setting up Camp 题目分析: 有三种人&#xff0c;内向、外向、综合&#xff0c;内向必须独自一个帐篷&#xff0c;外向必须3个人一个帐篷&#xff0c;综合介于1~3人一个帐篷&#xff0c;我们发现非法情况只会存在外向的人凑不成3个人一个帐篷的情况&#xff0c;因外向不够可…

JavaEE--小Demo

目录 下载包 配置 修改文件 pom.xml application.properties 创建文件 HelloApi.java GreetingController.java Greeting.java DemoApplication.java 运行包 运行命令 mvn package cd target dir java -jar demo-0.0.1-SNAPSHOT.jar 浏览器测试结果 下载包 …

为什么大家都在“挺”鸿蒙?

试想某一天&#xff0c;应用软件能够在手机、电视、手表甚至汽车等设备上&#xff0c;实现无缝流转、纵享丝滑。 这不仅是畅想&#xff0c;而是鸿蒙正在布局的“遥遥领先”。 随着HarmonyOS NEXT鸿蒙星河版面向开发者开放申请、鸿蒙原生应用版图的基本成型&#xff0c;这个国…

智慧水务:雨季山区水域水务智能化监控与监测管理方案

一、方案背景 雨季的水务管理对于各区县来说&#xff0c;无疑是一项至关重要的任务。夏季雨水充沛&#xff0c;江河湖泊水位上涨&#xff0c;山洪、上游排水等情况时有发生&#xff0c;给各地的水务设施和防汛工作带来了严峻的挑战。针对区县的各类水域监管场景&#xff0c;需…

如何在edge上安装拓展weTab

1.点解管理拓展 2.点击获取拓展 3.搜索框输入"wetab"并搜索 4.点击获取按钮 5.点击之后跳出弹窗,点击"添加拓展" 6.回到拓展页面,找到wetab拓展,点击右侧启动拓展 7.打开新的界面,wetab已经启动 8.自定义界面 1. 右键图标可以进行删除操作 2.左下角有个设…

ts版本微信小程序在wxml保存文件不刷新页面的解决办法

将project.config.json中的skylineRenderEnable改为false "skylineRenderEnable": false

HTTP协议1

官网学习网址&#xff1a;HTTP | MDN 常规信息 常规请求头信息&#xff1a; 状态码&#xff1a; 200 正常响应 404 未找到资源 500 服务端一场的 3** 重定向 资源缓存 响应头信息&#xff1a; 客户端允许的请求方法类型 Access-Control-Allow-Methods: GET, POST, PUT, DELET…

flutter 局部view更新,dialog更新进度,dialog更新

局部更新有好几种方法&#xff0c;本次使用的是 StatefulBuilder 定义 customState去更新对话框内容 import package:flutter/cupertino.dart; import package:flutter/material.dart;class ProgressDialog {final BuildContext context;BuildContext? dialogContext;double _…

【FAQ】BSV区块链代码库常见问题解答

​​发表时间&#xff1a;2024年2月27日 BSV区块链协会上线了JavaScript和TypeScript SDK&#xff08;即“标准开发工具包”&#xff09;。TypeScript SDK旨在为开发者提供新版统一核心代码库&#xff0c;让开发者可以在BSV区块链上便捷地进行开发&#xff0c;尤其是开发那些可…

1.实用Qt:解决绘制圆角边框时,圆角锯齿问题

目录 问题描述 解决方案 方案1&#xff1a; 方案2&#xff1a; 结果示意图 问题描述 做UI的时候&#xff0c;我们很多时候需要给绘制一个圆角边框&#xff0c;初识Qt绘制的童鞋&#xff0c;可能绘制出来的圆角边框很是锯齿&#xff0c;而且粗细不均匀&#xff0c;如下图&…

掌握增长转化漏斗策略的秘诀:打造高效营销之道

在不断发展的销售和营销领域&#xff0c;传统战略通常遵循一条可预测的路径&#xff0c;引导潜在客户通过漏斗&#xff0c;最终实现销售。然而&#xff0c;一种有趣的方法颠覆了这一传统模式&#xff1a;增长漏斗策略。这种创新方法重新规划了客户旅程&#xff0c;强调了培养现…

如何在wps的excel表格里面使用动态gif图

1、新建excel表格&#xff0c;粘贴gif图到表格里面&#xff0c;鼠标右键选择超链接。 找到源文件&#xff0c; 鼠标放到图片上的时候&#xff0c;待有个小手图标&#xff0c;双击鼠标可以放大看到动态gif图。 这种方式需要确保链接的原始文件位置和名称不能变化&#xff01;&a…

Java中的I/O讲解(超容易理解)(上篇)

如果想观看更多Java内容 可上我的个人主页关注我&#xff0c;地址子逸爱编程-CSDN博客https://blog.csdn.net/a15766649633?spm1000.2115.3001.5343使用工具 IntelliJ IDEA Community Edition 2023.1.4 使用语言 Java8 代码能力快速提升小方法&#xff0c;看完代码自己敲一…

已经准备上千道软件测试面试题了,建议大家收藏!!!还有视频详解!

1、你的测试职业发展是什么? 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自己&#xff0c;不…

Linux手动创建用户不使用useradd【七步走完成】

文章目录 第一步&#xff1a;修改 /etc/passwd 文件第二步&#xff1a;修改 /etc/shadow 文件第三步&#xff1a;修改 /etc/group 文件第四步&#xff1a;新建用户家目录第五步&#xff1a;复制/etc/skel目录下的环境变量配置文件到家目录下第六步&#xff1a;修改家目录的权限…

AI基础知识(2)--决策树,神经网络

1.什么是决策树&#xff1f; 决策树是一类常见的机器学习方法&#xff0c;决策树是基于树的结构来进行决策。决策过程中提出的每一个问题都是对于属性的“测试”&#xff0c;决策的最终结论对应了我们希望的判定结果。一个决策树包含一个根节点&#xff0c;若干个内部节点和若…

这个简单的生活方式,为你带来满满的幸福感

在今天文章的开头&#xff0c;我想请你思考一个问题&#xff1a;影响幸福感的最大因素是什么&#xff1f; 不妨先想一想&#xff0c;再往下拉&#xff0c;继续阅读。 可能不少朋友的回答&#xff0c;会是财富、事业、理想、生活环境、社会地位…… 这些因素当然对幸福感都非常重…

震惊!多数408院校复试线炸穿天际!

兄弟们&#xff0c;别盯着408有多难&#xff0c;你去看看408有多卷 都说408难&#xff0c;可是都去卷408&#xff0c;这是什么意思&#xff0c;一个个的算盘打的比谁都精 还不是因为考408的院校多&#xff0c;机会比较多&#xff0c;不像自命题不好换学校&#xff0c;全国一共…

模板(初阶)

一、介绍&#xff1a; 1.1模板目的&#xff1a; 将重复的活&#xff0c;从程序员手中交给编译器执行。 1.2泛型编程&#xff1a; 编写与类型无关的通用代码&#xff0c;实现代码的复用。 二、函数模板&#xff1a; 2.1函数模板&#xff1a; 函数模板代表了一个函数家族&…

spring boot3登录开发-2(2短信验证码接口实现)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途 目录 写在前面 上文衔接 内容简介 短信验证码接口实现 1.依赖导入 2.接口分析 3.实现思路 3.功能实现 创建发送短信…