装饰者模式

news2024/11/28 20:59:29

采用组合而非继承的手法,Decorator模式实现了在运行时动态扩展对象功能的能力,可以根据需要扩展功能。

Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类的所有接口。但在实现上又表现为has-a Component的组合关系,即Decorator类里有Component类的指针。

装饰者模式既有继承,又有组合。

Decorator模式主要解决 主体类在多个方向上的扩展功能,这就是装饰的含义。

 框选部分存在大量重复代码以及子类泛滥的问题。本质上不是继承关系,所以使用继承关系就会出现此问题。正确的关系时来扩展。应该变为下图的关系。

 

#include <iostream>
#include <memory>

//抽象构件 定义了一个,用于规范具体构件和装饰者的行为
class Component {
public:
	virtual void operation() = 0;
	virtual ~Component() { std::cout << "Component析构函数" << std::endl; }
};
//ConcreteComponent是具体构件,实现了Component接口,它是被装饰的对象
class ConcreteComponent : public Component {
public:
	void operation() {
		std::cout << "ConcreteComponent::operation()" << std::endl;
	}
	virtual ~ConcreteComponent() { std::cout << "ConcreteComponent析构函数" << std::endl; }
};
//Decorator是装饰者,它实现了Component接口,并持有一个指向Component的指针
//,用于装饰Component对象,同时还可以自定义一些额外的行为
class Decorator : public Component {
public:
	Decorator(Component* component) : m_component(component) {}
	virtual ~Decorator() { std::cout << "Decorator析构函数" << std::endl; }
	void operation() {
		m_component->operation();
	}

protected:
	Component* m_component;
};

class ConcreteDecoratorA : public Decorator {
public:
	ConcreteDecoratorA(Component* component) : Decorator(component) {}
	~ConcreteDecoratorA() { std::cout << "ConcreteDecoratorA析构函数" << std::endl; }
	void operation() {
		Decorator::operation();
		std::cout << "ConcreteDecoratorA::operation()" << std::endl;
	}
};

class ConcreteDecoratorB : public Decorator {
public:
	ConcreteDecoratorB(Component* component) : Decorator(component) {}
	 ~ConcreteDecoratorB() { std::cout << "ConcreteDecoratorB析构函数" << std::endl; }
	void operation() {
		Decorator::operation();
		std::cout << "ConcreteDecoratorB::operation()" << std::endl;
	}
};

int main() {
	std::unique_ptr<Component> component(std::move(new ConcreteComponent()));
	component->operation();

	std::unique_ptr<Component> concreteDecoratorA(new ConcreteDecoratorA(component.get()));
	concreteDecoratorA->operation();

	std::unique_ptr<Component> concreteDecoratorB(new ConcreteDecoratorB(concreteDecoratorA.get()));
	concreteDecoratorB->operation();

	return 0;
}

装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时动态地添加功能到类中,避免了通过继承来实现功能增强的复杂度。

装饰者模式的应用场景包括:

  1. 当需要在不改变原有类结构的情况下,对类进行功能增强时,可以使用装饰者模式。
  2. 当需要动态地添加或删除类的功能时,可以使用装饰者模式。
  3. 当需要对一个类的功能进行多次扩展时,可以使用装饰者模式

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

打印流~~

文章目录 打印流PrintStreamPrintWriter追加操作输出语句的重定向 Properties使用properties把键值对信息存入到属性文件中去使用properties在文件中取键值对信息 IO框架(了解) 打印流 作用&#xff1a;打印流可以实现方便、高效的打印数据到文件中去。打印流一般是指&#xff…

【Linux】2.1 环境基础开发工具使用——yum

什么是yum Linux 软件包管理器——yum yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器. 主要应用在Fedora, RedHat, Centos等发行版上. yum 的使用 卸载&#xff1a; yum -y(直接卸载) remove [xxx] 查找&#xff1a; yum list | grep [xxx] 软件包名称:…

这才是 SpringBoot 统一登录鉴权、异常处理、数据格式 的正确姿势

本篇将要学习 Spring Boot 统一功能处理模块&#xff0c;这也是 AOP 的实战环节 用户登录权限的校验实现接口 HandlerInterceptor WebMvcConfigurer 异常处理使用注解 RestControllerAdvice ExceptionHandler 数据格式返回使用注解 ControllerAdvice 并且实现接口 Response…

Hive拉链表实现

拉链表 定义:用来记录历史变化,相比每天存储全量数据,可大幅减少数据冗余,可以基于历史变化,统计分析历史变化信息使用场景: 用于记录维度变化场景,记录维度变化,根据维度变化记录,统计聚合,加成生成不同时期历史指标 Hive 拉链表实现 实现原理 首次(T1: 2023-04-01) 同步业…

MATLAB-Lingo求解线性规划问题-奶制品2

奶制品的生产销售计划&#xff0c;给定条件不变 为了增加工厂的获利&#xff0c;开发了奶制品的深加工技术&#xff1a;用2小时和3元加工费&#xff0c;可将1kgA1加工成0.8kg高级奶制品B1&#xff0c;也可将1kgA2加工成0.75kg高级奶制品B2&#xff0c;每千克B1能获利44元&#…

ABI Research产业研究:ZiFiSense如何革新物流货物及运输包装追踪

“文章源自前沿科技研究机构ABI Research产业研究&#xff0c;重点介绍了ZETA LPWA协议开发公司纵行科技在业务发展、M-FSK调制技术以及ZETag云标签系列产品在物流货物追踪与包装管理等方面的应用分析&#xff0c;还分享了纵行科技ZETA技术在商业市场和生态系统方面的发展情况。…

用扩展方法来实现EventTrigger中事件的异步等待

一、什么是扩展方法&#xff1f; 扩展方法是一种C#语言提供的功能&#xff0c;允许我们向现有类型添加新的方法&#xff0c;而无需修改类型的源代码。扩展方法的优缺点如下&#xff1a; 二、它有什么优点&#xff1f; 1、不需要修改源类型的代码&#xff1a;使用扩展方法可以…

工具-Snipaste与ScreenToGif 生产力工具,对截图进行勾画操作,并可将截图贴至电脑任意界面;快捷动态截图成gif

文章目录 1、演示1.1 snipaste1.2 ScreenToGif 2、操作2.1 snipaste2.2 ScreenToGif 1、演示 1.1 snipaste 1.2 ScreenToGif 2、操作 2.1 snipaste 进入官网&#xff0c;可根据系统进行下载 https://zh.snipaste.com/ 傻瓜式安装成功后&#xff0c;电脑的右下角有个小图标&a…

兰林:科技赋能健康产业 助力乡村振兴建设

万民健康创始人 万民智养中医创始人 万民星农CEO兰林 党建引领谋发展 &#xff0c; 旗帜下乡促振兴 。 乡村振兴&#xff0c;健康先行。自党的十八大以来&#xff0c;国家卫健委贯彻落实“以基层为重点”的党的卫生与健康工作方针&#xff0c;推动医疗卫生工作重心下移、资源下…

Springboot +Flowable,通过代码绘制流程图并设置高亮

一.简介 通过代码绘制一张流程图&#xff0c;并设置成高亮。 首先先来看一下绘制出来的效果图&#xff0c;截图如下&#xff1a; 已经执行的节点和连线用红色标记出来&#xff0c;大致上就是这么一个效果。 二.怎么实现 将一个流程图绘制成图片&#xff0c;相关的 API 在…

倾斜摄影超大场景的三维模型的顶层合并的轻量化处理技术

倾斜摄影超大场景的三维模型的顶层合并的轻量化处理技术 倾斜摄影超大场景的三维模型的顶层合并需要进行轻量化处理&#xff0c;以减小数据量和提高数据的传输和展示性能。以下是几种常用的轻量化处理技术&#xff1a; 1、网格简化&#xff1a;对三角面片数量过多的模型进行网…

10个常用的软件测试工具,你不容错过

在现代软件开发中&#xff0c;软件测试是不可或缺的一部分。为了确保软件产品的质量和稳定性&#xff0c;软件测试工具成为了测试团队的得力助手。 有许多优秀的软件测试工具可以帮助测试人员在各种测试活动中提高效率和准确性。 本文将介绍10个常用的软件测试工具&#xff0c;…

LeetCode第141题——环形链表(Java)

题目描述&#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链…

多线程|基于阻塞队列和环形队列的生产者消费者模型架构

前言 那么这里博主先安利一下一些干货满满的专栏啦&#xff01; Linux专栏https://blog.csdn.net/yu_cblog/category_11786077.html?spm1001.2014.3001.5482操作系统专栏https://blog.csdn.net/yu_cblog/category_12165502.html?spm1001.2014.3001.5482手撕数据结构https:/…

办公软件中可以使用chatGPT吗?

随着ONLYOFFICE新品协作空间的发布&#xff0c;有很多朋友已经开始在工作区或桌面版用上chatGPT的朋友担心&#xff0c;在协作空间是否也可以正常使用chatGPT&#xff0c;我可以很负责的告诉大家&#xff0c;完全可以正常使用。 什么是ONLYOFFICE协作空间&#xff1f; 简言之&…

Java8新特性--Lambda表达式

一、简述 Lambda 表达式&#xff0c;也可称为闭包&#xff0c;它 允许把函数作为一个方法的参数 (函 数作为参数传递进方法中) Lambda 简化了匿名内部类的形式&#xff0c; 可以达到同样的效果&#xff0c;匿名内部类在 编译之后会创建一个新的匿名内部类 出来&#xff0c;而 L…

Daftart.ai:人工智能专辑封面生成器

前言 Daft Art AI是一款使用人工智能技术来帮助您制作专辑封面的软件&#xff0c;它可以让您在几分钟内&#xff0c;用简单的编辑器和精选的美学风格&#xff0c;为您的专辑或歌曲创建出惊艳的高质量的艺术品。Daft Art AI有以下几个特点&#xff1a;简单易用&#xff1a;您只…

CVE漏洞复现-CVE-2019-11043-PHP-FPM 远程代码执行漏洞

CVE-2019-11043-PHP-FPM 远程代码执行漏洞 漏洞描述 来自Wallarm的安全研究员Andrew Danau在9月14-16号举办的Real World CTF中&#xff0c;意外的向服务器发送%0a(换行符)时&#xff0c;服务器返回异常信息。由此发现了这个0day漏洞 当Nginx使用特定的 fastcgi 配置时&…

Java学习14(ThreadLocal详解)

对于ThreadLocal&#xff0c;大家的第一反应可能是很简单呀&#xff0c;线程的变量副本&#xff0c;每个线程隔离。那这里有几个问题大家可以思考一下&#xff1a; ThreadLocal的 key 是弱引用&#xff0c;那么在 ThreadLocal.get()的时候&#xff0c;发生GC之后&#xff0c;k…

Python小姿势 - # 如何在Python中实现基本的数据类型

如何在Python中实现基本的数据类型 Python是一门面向对象的编程语言&#xff0c;基本的数据类型包括整数、浮点数、字符串、布尔值、列表、元组、字典等。 整数是最基本的数据类型&#xff0c;一个整数可以是任意大小的&#xff0c;只要内存允许。 浮点数也称为实数&#xff0c…