Dectorator:装饰模式

2023-10-27

      要为一个类扩展功能,那么可以使用派生,然后由派生类实现扩展的功能。

      但,若扩展的是个临时功能,或者可能扩展多个不确定功能,就需要使用装饰模式。装饰模式允许为一个类临时添加任意其他功能,并可以任意组合。

      装饰模式可以在不生成子类的情况下为对象添加职责

 

1.    定义Component

该类是被装饰类与装饰类的共同基类。该类规定了被装饰类的操作接口。

class Component
{
public:
	virtual void Operation() = 0;
protected:
	Component();
};

2.    定义原始类

即需要被扩展的类。该类从Component类派生。

在实际应用中,该类的对象需要通过装饰类来添加额外功能。

class ConcreteComponent :public Component
{
public:
	ConcreteComponent();
	virtual void Operation();
};

3.    定义装饰类

装饰类用于扩展原始类。扩展后,装饰类将代替原始类。所以装饰类与原始类从同一个父类派生

同时,为了保留原始类的功能,将原始类以组合的形式内嵌到装饰类中

由于装饰可能有多种,所以从共同父类Component派生一个装饰类基类,然后由该基类再派生不同的装饰类。

//Decorator:装饰抽象类,继承自Component
class Decorator :public Component
{
public:
	Decorator(Component* com)
	{
		this->_com = com;
	};

	void SetComponent(Component* com);
	virtual void Operation();
protected:
	Component* _com;
};

//装饰类A
class ConcreteDecoratorA :public Decorator
{
public:
	ConcreteDecoratorA(Component* com);

	void AddBehavorA();

	virtual void Operation()
	{
		this->_com->Operation();
		//附加职责A
		this->AddBehavorA();
	};
};

//装饰类B
class ConcreteDecoratorB :public Decorator
{
public:
	ConcreteDecoratorB(Component* com);
	void AddBehavorB();

	virtual void Operation()
	{
		this->_com->Operation();
		//附加职责B
		this->AddBehavorB();
	};
};

4.    用户使用

void main()
{
	Component* pComponent = new ConcreteComponent();	//要装饰的对象
	Decorator* pDecorator = NULL;
	pDecorator = new ConcreteDecoratorA(pComponent);	//附加职责A
	pDecorator = new ConcreteDecoratorB(pDecorator);	//附加职责B
	pDecorator->Operation();

	delete pDecorator;
}

      由Dectorator模式的结构可知,每个Dectorator类都提供一个扩展功能。 如果需要多个扩展功能,可以进行多层嵌套。因为每个Dectorator类都是一个 Component,因此也可以被进一步嵌套为其他Dectorator类。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dectorator:装饰模式 的相关文章

  • C++ std::accumulate 没有给出预期的总和

    double numbers 1 0 5 0 333333 0 25 0 2 0 166667 0 142857 0 125 0 111111 0 1 std vector
  • 无法在 QGLWidget 中设置所需的 OpenGL 版本

    我正在尝试在 Qt 4 8 2 中使用 QGLWidget 我注意到 QGLWidget 创建的默认上下文不显示 OpenGL 3 1 以上的任何输出 Qt wiki 有一个教程 http qt project org wiki How t
  • EF Core 返回 null 关系,直到直接访问

    我有一些如下所示的模型 public class Mutant public long Id get set Relations public long OriginalCodeId get set public virtual Origi
  • 使用管道在父级和子级之间传递整数值

    我对如何正确使用 pipeline 在两个进程之间传递整数值有点困惑 在我的程序中 我首先创建一个管道 然后分叉它 我假设我有 两个 管道 据我了解 这是我的任务 我的父母通过 for 循环检查某个操作的整数值 i 增加计数变量 并将值保存
  • SOAP Web 服务:多台服务器,一个接口

    我有一个场景 需要任意数量的服务器来提供相同的 SOAP Web 服务 我想生成一组代理类 并能够为它们提供一个位置 以便在运行时将它们指向不同的服务器 不幸的是 看起来好像wsdl port节点 子节点wsdl service 要求对特定
  • 无法在 CUDA 中找到 1 到 100 数字的简单和?

    我正在研究使用 CUDA 的图像处理算法 在我的算法中 我想使用 CUDA 内核找到图像所有像素的总和 所以我在cuda中制作了内核方法 来测量16位灰度图像的所有像素的总和 但我得到了错误的答案 所以我在cuda中编写了一个简单的程序来查
  • 我担心我添加了太多接口

    我正在构建我的领域模型并继续重构它 正如我所做的那样 我发现我喜欢接口 因为它允许我根据接口为具体类型创建可重用的方法 控制器 视图 但是 我发现每次向域实体之一添加新属性时 我都会创建一个接口 例如 我有一个会员状态从抽象继承的对象Ent
  • 如何在 Linux 上重新实现(或包装)系统调用函数?

    假设我想完全接管 open 系统调用 也许要包装实际的系统调用并执行一些日志记录 一种方法是使用 LD PRELOAD http scaryreasoner wordpress com 2007 11 17 using ld preload
  • 在 C# 中解析 JS Date.toIsoString

    我需要将 JS 日期存储为 ISO 8601 日期 我目前正在从格式为 2019 06 22T00 00 00 000Z 的表单中获取日期 正如 JS 的 toIsoString 方法所期望的那样 当这个日期传递到我的 API 控制器时 我
  • 用于 C++ 中图像分析的 OpenCV 二进制图像掩模

    我正在尝试分析一些图像 这些图像的外部周围有很多噪声 但内部有一个清晰的圆形中心 中心是我感兴趣的部分 但外部噪声正在影响我对图像的二进制阈值处理 为了忽略噪音 我尝试设置一个已知中心位置和半径的圆形蒙版 从而使该圆之外的所有像素都更改为黑
  • 注入包含接口的所有已注册实现的 Enumerable

    给出以下接口 public interface IMyProcessor void Process 我希望能够注册多个实现 并让我的 DI 容器将它们的可枚举注入到这样的类中 public class MyProcessorLibrary
  • X 轴和 Z 轴上的 Quaternion.Slerp,无 Y 轴

    I am trying to rotate the Player about X Y and Z axis The Y axis should not move from last angle Example if I rotate 45
  • 使用任一默认捕获模式时,这是通过复制捕获还是 (*this) 通过引用捕获?是一样的吗?

    当我看到以下工作时我有点困惑 struct A void g void f g 但后来我发现this https stackoverflow com a 16323119 5825294答案非常详细地解释了它是如何工作的 本质上 它归结为t
  • main.cpp 是必需的吗?

    我试图编译一个程序cmake 我最终删除了我的main cpp文件 我刚刚将其复合到另一个包含我的项目名称的文件中 即 我刚刚将主函数剪切并粘贴到该文件中 问题是我有一个main cpp未发现错误 不确定是否在C 一个名为main cpp是
  • 如何在VS2005中使用从.bat而不是.exe启动的外部程序进行调试?

    在我的 c 项目的调试属性中 我选择了 启动外部程序 并选择了我希望将调试器附加到的程序的 exe 但是 现在我需要从 bat 文件而不是 exe 启动程序 但 VS2005 似乎不允许这样做 这可能吗 编辑 为了澄清 我需要调试从 bat
  • 在 clang 中向量化函数

    我正在尝试根据此用 clang 对以下函数进行矢量化铿锵参考 http llvm org docs Vectorizers html 它采用字节数组向量并根据以下条件应用掩码this RFC https www rfc editor org
  • 从单应性估计 R/T

    我一直在尝试计算 2 个图像中的特征 然后将这些特征传递回CameraParams R没有运气 特征已成功计算并匹配 但是问题是将它们传递回R t 我明白你必须分解Homography为了使这一点成为可能 我已经使用如下方法完成了 http
  • 在 Visual Studio 2012 Express 中设置 C++ 调试环境

    我需要调试的应用程序需要设置环境变量 这在 Visual Studio 2012 中似乎非常复杂 我想做类似的事情 set path c foo c bar c windows c program files application set
  • 如何防止 Lotus Notes 用户转发或复制通过 System.Net.Mail 发送的邮件?

    我想使用 SMTP 客户端 uiing microsft net 以 C 作为编程语言发送电子邮件 但是对于通过SMTP客户端发送的电子邮件 我们是否可以添加 禁止转发 或 禁止复制 等安全功能 我不希望电子邮件的收件人转发或复制电子邮件的
  • NHibernate:无状态会话错误消息无法获取代理

    我正在使用 nHibernate 无状态会话来获取对象 更新一个属性并将对象保存回数据库 我不断收到错误消息 无状态会话无法获取代理 我在其他地方有类似的代码 所以我不明白为什么这不起作用 有谁知道问题可能是什么 我正在尝试更新Screen

随机推荐

  • PowerMock--Mock静态方法

    1 PowerMock静态方法 写单元测试时 经常会遇到测试方法体内调用了某些工具类的静态方法的情况 而这些静态方法一般是读取配置中心里的文件数据 或者是一些其他涉及到需要启动项目的操作 往往这些操作会造成Mock单元测试的不彻底 有些流水
  • 排序算法之快速排序

    高快省的排序算法 有没有既不浪费空间又可以快一点的排序算法呢 那就是 快速排序 啦 光听这个名字是不是就觉得很高端呢 假设我们现在对 6 1 2 7 9 3 4 5 10 8 这个10个数进行排序 首先在这个序列中随便找一个数作为基准数 不
  • 【福利】南昌大学NCU主题电子笔记本,免费获取!

    转载请注明出处 小锋学长生活大爆炸 xfxuezhang cn 禁止转卖 恰烂钱可耻 下载链接 https pan baidu com s 1RWVrQgbmth CwoTcY 1yVw pwd 5gu8
  • MATLAB——基于自回归积分移动平均线 (ARIMA) 模型对数据进行预测

    通过1985至20222年各年的参加测试人数为实际数据 通过ARIMA模型对未来十年参加测试人数进行预测 clc clear Y data 2 N length Y t 1985 2022 figure 1 plot t Y title 高
  • 数据库性能优化的误区!

    常见的数据库系统优化中的一些观点 系统性能出现问题进行优化 一定要深入了解数据库内部参数 等待事件 Latch 缓冲池 trace文件 查询 优化引擎等底层细节 这种观点往往出自数据库 高手 这部分人以了解数据库底层实现细节而感到非常骄傲
  • Python文件指针

    实验文件data txt如下 This file is data txt hello world My name is mark 实验一 文件指针初始化 f open data txt r print f tell f write nice
  • matlab读取.dat数据

    任务 手上有一个dat后缀名文件 需要导入matlab 并对其中的每一列数据进行处理 解决方案 导入数据 S1 点击 导入数据 按钮 弹出导入数据窗口 S2 选择 范围 因为第一行是标题 所以我不想导入 导入范围从A2开始 到G436结束
  • Notes Twenty one days-渗透攻击-红队-权限提升

    Notes Twenty one days 渗透攻击 红队 权限提升 dayu 作者 大余 时间 2020 10 7 请注意 对于所有笔记中复现的这些终端或者服务器 都是自行搭建的环境进行渗透的 我将使用Kali Linux作为此次学习的攻
  • 获取系统磁盘类型信息以及判断是否是U盘

    使用WIN API函数实现 include
  • Web渗透测试实战——(1)Web渗透测试简介

    一 什么是渗透测试 渗透测试 penetration testing 是对计算机系统的一种授权攻击 旨在评估系统 网络的安全性 执行测试以识别漏洞及其带来的风险 一般而言 渗透测试过程分为五个阶段 包括识别目标系统 检测存在的漏洞以及每个漏
  • Java基础系列30-单列 Collection集合

    文章目录 一 集合的概述 1 1 为什么会出现集合类 1 2 集合类体系结构图 二 Collection集合 2 1 Collection集合入门 2 2 Collection集合的成员方法 2 3 Collection集合的遍历 2 4
  • vue使用vue-amap 高德地图进行选点和搜索

    vue使用vue amap进行地图点的搜索和点击选点 npm install vue amap save 下载npm 包 在main js主文件中进行引用 import VueAMap from vue amap Vue use VueAM
  • C++连接CTP接口实现简单量化交易(行情、交易、k线、策略)

    对于量化交易来说 量化策略和技术系统缺一不可 为了知其所以然 本文实现了一个C 连接CTP接口进行仿真交易的demo 从接收行情 下订单 数据处理到添加策略 挂载运行交易等多个环节来看一下量化交易的最简单流程 管中窥豹 一探究竟 准备工作
  • NetworkManager 使用

    Network Manager Network Manager aims for Network Connectivity which Just Works The computer should use the wired network
  • clickhouse源码:函数分析和自定义函数UDF

    clickhouse函数介绍 clickhouse官方提供了许多的函数 包括常规的数学函数 聚合函数 时间函数 逻辑函数 比较函数等等 关于官方的函数可以在官方文档中查看 官方文档 当然随着clickhouse的流行 国内也有不少的博主已经
  • 《星岛日报》专访:欧科云链AML,助力数字资产合规及风险防控

    6月1日 香港 适用于虚拟资产交易平台营运者的指引 及 打击洗钱指引 正式施行 香港虚拟资产发牌制度正式生效 作为深耕香港市场多年的Web3科技企业 欧科云链OKLink也正式推出的Onchain AML反洗钱合规解决方案 利用多年积累的海
  • python如何建立一个空集合_python的集合set

    一 集合set 概念 1 集合set是一组无序不可重复的key集合 2 set跟dict的key类似 区别在于set没有value 3 set使用场景 1 判断某个元素是否在集合中 2 消除输入数据的重复元素 二 set 的创建方式 1 创
  • timm 视觉库中的 create_model 函数详解

    timm 视觉库中的 create model 函数详解 最近一年 Vision Transformer 及其相关改进的工作层出不穷 在他们开源的代码中 大部分都用到了这样一个库 timm 各位炼丹师应该已经想必已经对其无比熟悉了 本文将介
  • 经典不衰数据可视化项目第一节(共享单车项目)

    1 1 首先导入包 import pandas as pd import numpy as np import matplotlib pyplot as plt import seaborn as sns import datetime i
  • Dectorator:装饰模式

    要为一个类扩展功能 那么可以使用派生 然后由派生类实现扩展的功能 但 若扩展的是个临时功能 或者可能扩展多个不确定功能 就需要使用装饰模式 装饰模式允许为一个类临时添加任意其他功能 并可以任意组合 装饰模式可以在不生成子类的情况下为对象添加