装饰模式C++实现

2023-05-16

简介

动态地给一个对象添加一些额外的职责。
就增加功能来说,装饰模式比生成子类更为灵活。

动机

有时我们希望给某个对象而不是整个类添加一些功能。
使用继承机制是添加功能的一种有效途径,但不够灵活,用户不能控制对组件添加功能的方式和时机。
一种较为灵活的方式是将组件嵌入另一个对象中,由这个对象添加功能,我们称这个嵌入的对象为装饰。
这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。

适用性

在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
处理那些可以撤销的职责。
当不能采用生成子类的方法进行扩充时。
可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。
类定义被隐藏,或类定义不能用于生成子类。

结构

在这里插入图片描述

装饰模式的参与者

Component
定义一个对象接口,可以给这些对象动态地添加职责。
ConcreteComponent
定义一个对象,可以给这个对象添加一些职责。
Decorator
维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。
ConcreteDecorator
向组件添加职责。

装饰模式的协作

Decorator将请求转发给它的Component对象,并有可能在转发请求前后执行一些附加动作。

效果

比静态继承更灵活
避免在层次结构高层的类有太多的特征
Decorator与它的Component不一样
有许多小对象

注意点

如果只有一个ConcreteComponent类而没有Component类,那么Decorator类可以是ConcreteComponent的一个子类。
同理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator合并成一个类。

实例

给定两种初始的汽车类,例如丰田和沃尔沃,利用装饰模式分别给它们添加新的功能,其中丰田可以导航和自动驾驶,沃尔沃可以导航和语音控制。

UML图

在这里插入图片描述

代码与函数

Component:Car类

ConcreteComponent:TOYOTA、VOLOVO类

Decorator:Function类

ConcreteDecorator:Navigator、SelfDrive、VoiceControl类

代码

#include<iostream>
using namespace std;
 
/*
给定两种初始的汽车类,例如丰田和沃尔沃,
利用装饰模式分别给它们添加新的功能,
其中丰田可以导航和自动驾驶,沃尔沃可以导航和语音控制。
*/
 
class Car{//Component
public:
    virtual void showInfo() = 0;
};
 
class TOYOTA: public Car{
public:
    TOYOTA(){}
    TOYOTA(string name){
        this->name = name;
    }
    void showInfo(){
        cout<<name<<endl;
    }
private:
    string name;
};
 
class  VOLOVO: public Car{
public:
    VOLOVO(){}
    VOLOVO(string name){
        this->name = name;
    }
    void showInfo(){
        cout<<name<<endl;
    }
private:
    string name;
};
 
class Function: public Car{//Decorator
protected:
    Car* car;
public:
    void Decorate(Car* car){
        this->car = car;
    }
    void showInfo(){
        if(car != NULL)car->showInfo();
    }
};
 
//其中丰田可以导航和自动驾驶,沃尔沃可以导航和语音控制。
 
class Navigator: public Function{
public:
    void showInfo(){
        cout<<"导航 ";
        Function::showInfo();
    }
};
 
class SelfDrive: public Function{
public:
    void showInfo(){
        cout<<"自动驾驶 ";
        Function::showInfo();
    }
};
 
class VoiceControl: public Function{
public:
    void showInfo(){
        cout<<"语音控制 ";
        Function::showInfo();
    }
};
 
 
//其中丰田可以导航和自动驾驶,沃尔沃可以导航和语音控制。
int main(){
    Car* toyota = new TOYOTA("丰田卡罗拉");
    Navigator* na = new Navigator();
    SelfDrive* sd = new SelfDrive();
    na->Decorate(toyota);
    sd->Decorate(na);
    sd->showInfo();
    cout<<endl;
    
    Car* volovo = new VOLOVO("沃尔沃S90");
    Navigator* na2 = new Navigator();
    VoiceControl* vc = new VoiceControl();
    na2->Decorate(volovo);
    vc->Decorate(na2);
    vc->showInfo();
 
    return 0;
}

总结

①本次实验通过Car的实例掌握并编码了装饰模式。

②注意如果只有一个ConcreteComponent类而没有Component类,那么Decorator类可以是ConcreteComponent的一个子类。在本次实验中,有TOYOTA和VOLOVO两个具体的类,因此需要一个Component的Car类来定义接口。

③由②可知,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator合并成一个类。在本次实验中有Navigator、SelfDrive、VoiceControl三个具体的装饰类。

④在客户端中,要最后一个添加的职责,用来是包装好了的车对象,因此需要由最后一个装饰的实例显示结果。

更多内容访问 omegaxyz.com
网站所有代码采用Apache 2.0授权
网站文章采用知识共享许可协议BY-NC-SA4.0授权
© 2019 • OmegaXYZ-版权所有 转载请注明出处

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

装饰模式C++实现 的相关文章

  • 反世代距离评价指标IGD

    反世代距离评价指标 Inverted Generational Distance IGD 是一个综合性能评价指标 它主要通过计算每个在真实 Pareto前沿面上的点 个体 到算法获取的个体集合之间的最小距离和 xff0c 来评价算法的收敛性
  • 遗传算法解决TSP问题MATLAB实现(详细)

    问题定义 xff1a 巡回旅行商问题 给定一组n个城市和俩俩之间的直达距离 xff0c 寻找一条闭合的旅程 xff0c 使得每个城市刚好经过一次且总的旅行距离最短 TSP问题也称为货郎担问题 xff0c 是一个古老的问题 最早可以追溯到17
  • 二叉树遍历的转换C++实现

    二叉树的遍历分为以下三种 xff1a 先序遍历 xff1a 遍历顺序规则为 根左右 中序遍历 xff1a 遍历顺序规则为 左根右 后序遍历 xff1a 遍历顺序规则为 左右根 什么是 根左右 就是先遍历根 xff0c 再遍历左节点 xff0
  • Java数据存取对象(DAO)

    什么是DAO DAO xff08 Data Access Object xff09 顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象 xff0c 在不暴露底层持久化方案实现细节的前提下提供了各种数据访问操作 在实际的开发中 xff
  • 经典蝙蝠算法MATLAB实现

    为什么会有这么多基于群智能的算法 xff0c 蚁群 粒子群 鱼群 烟花 炮竹 猪群 牛群 马群 羊群 猴群 鸡群 算法 xff1f xff1f xff1f xff1f xff1f xff1f 黑人问号 jpg 蝙蝠算法 BA 是 Yang
  • 计算机领域顶级会议、期刊、人物与国家排名2019

    原文地址 xff1a 最近浏览到一个网站 xff1a http www guide2research com 这是一个根据谷歌学术排名的计算机领域各类会议 学术期刊 人物 国家 组织的排名查询网站 时间2019年3月 会议 按照Hindex
  • 基于迭代局部搜索和随机惯性权重的BA算法MATLAB实现(ILSSIWBA)

    BA算法简介 http www omegaxyz com 2019 02 12 ba matlab 该论文修改 作者在原有BA算法上进行3个修改 跳出局部最优 xff08 扰动个体 xff09 使得算法变得稳定脉搏和响度修改 xff0c 平
  • Ubuntu下pip的安装与升级

    安装 pip2 sudo apt get install python pip python dev build essential wukai 64 wukai sudo apt install python span class hlj
  • PyQt5多线程刷新界面防假死

    在做GUI界面时我们希望后台任务能够与UI分开 xff0c 在PyQt中 xff0c 主线程用来重绘界面 而子线程里边的实时处理结果需要反馈到界面 xff0c 子线程里边不能执行界面更新操作 wxpython多线程刷新界面转到 http w
  • NSGA2算法中文详解与MATLAB实现整理

    NSGA2算法 NSGA II多目标遗传算法概述 http www omegaxyz com 2017 04 14 nsga iiintro NSGA2算法MATLAB实现 xff08 能够自定义优化函数 xff09 http www om
  • 对极大似然估计的理解

    参数估计 xff08 parameter estimation xff09 统计推断的一种 根据从总体中抽取的随机样本来估计总体分布中未知参数的过程 从估计形式看 xff0c 区分为点估计与区间估计 xff1a 从构造估计量的方法讲 xff
  • 动态规划——最大整除子集C++

    来自LeetCode 368 描述 给出一个由无重复的正整数组成的集合 xff0c 找出其中最大的整除子集 xff0c 子集中任意一对 Si xff0c Sj 都要满足 xff1a Si Sj 61 0 或 Sj Si 61 0 如果有多个

随机推荐

  • HyperVolume多目标评价指标概述

    提出 Hypervolume 指标评价方法最早是由 Zitzler 等提出 xff0c 它表示由解集中的个体与参考点在目标空间中所围成的超立方体的体积 评价标准 Hypervolume 指 标 评 价 方 法 是 一 种 与 Pareto
  • 三路快排C++实现与应用

    本文共467个字 xff0c 预计阅读时间需要2分钟 三路快排是快速排序算法的升级版 xff0c 用来处理有大量重复数据的数组 主要思想是选取一个key xff0c 小于key的丢到左边 xff0c 大于key的丢到右边 xff0c 递归实
  • Wilcoxon秩和检验简介与MATLAB实现

    Wilcoxon秩和检验 rank sum test xff0c 有时也叫Mann Whitney U检验 xff0c 是另一类非参数检验方法 xff0c 它们不对数据分布作特殊假设 xff0c 因而能适用于更复杂的数据分布情况 适用性 x
  • FatMouse’ Trade

    简介 贪心算法 xff08 又称贪婪算法 xff09 是指 xff0c 在对问题求解时 xff0c 总是做出在当前看来是最好的选择 也就是说 xff0c 不从整体最优上加以考虑 xff0c 他所做出的是在某种意义上的局部最优解 贪心算法不是
  • 算法复杂度与NP问题

    引言 美剧 基本演绎法 S2E2中 xff0c 两位研究 NP 问题的数学家被谋杀了 xff0c 凶手是同行 xff0c 因为被害者即将证明 P 61 NP 问题 假设人类证明了P 61 NP 是真的 xff0c 那么就会有一个算法 xff
  • 素数筛C++

    埃拉托斯特尼筛法 xff08 sieve of Eratosthenes xff09 是古希腊数学家埃拉托斯特尼发明的计算素数的方法 对于求解不大于n的所有素数 xff0c 我们先找出sqrt n 内的所有素数p1到pk xff0c 其中k
  • ubuntu安装mysql-server环境解决无穷依赖问题

    问题 ubuntu14 04 3安装mysql时报错 xff1a sudo apt get install mysql server mysql client 正在读取软件包列表 完成 正在分析软件包的依赖关系树 正在读取状态信息 完成 有
  • Levenshtein编辑距离C++实现

    简介 Levenshtein Distance是1965年由苏联数学家Vladimir Levenshtein发明的 Levenshtein Distance也被称为编辑距离 xff08 Edit Distance xff09 在信息论和计
  • 红黑树简介与C++应用

    简介 红黑树 xff08 Red Black Tree xff09 是一种自平衡二叉查找树 xff0c 是在计算机科学中用到的一种数据结构 xff0c 典型的用途是实现关联数组 它是在1972年由Rudolf Bayer发明的 xff0c
  • 碰撞域与广播域的区别

    在说到碰撞域 xff08 冲突域 xff09 和广播域之前 xff0c 首先要介绍一下三个网络互连设备 集线器 交换机和路由器 集线器 集线器是工作在物理层的设备 xff0c 当他收到数据以后就把这个数据复制复制以后就把这个数据象所有的接口
  • WordPress数据库error establishing a database connection错误

    本文共777个字 xff0c 预计阅读时间需要2分钟 作为一个买不起大型服务器只能用阿里云学生机的站长 xff0c 经常遇到error establishing a database connection错误 这是一种建立数据库连接时的错误
  • 基于稀疏大规模矩阵的多目标进化算法简介

    简介 可以看到本文的特色图片是个极度稀疏连接的神经网络 xff0c 它是由我们即将介绍论文中的算法SparseEA得到的 此篇论文是BIMK的田野 张兴义等人发表在IEEE Transactions on Evolutionary Comp
  • 回溯法——素数环C++实现

    本文共928个字 xff0c 预计阅读时间需要3分钟 回溯法简介 回溯法按深度优先策略搜索问题的解空间树 首先从根节点出发搜索解空间树 xff0c 当算法搜索至解空间树的某一节点时 xff0c 先利用剪枝函数判断该节点是否可行 xff08
  • Prime Path素数筛与BFS动态规划

    本文共2053个字 xff0c 预计阅读时间需要6分钟 BFS BFS xff0c 其英文全称是Breadth First Search BFS并不使用经验法则算法 从算法的观点 xff0c 所有因为展开节点而得到的子节点都会被加进一个先进
  • C++读取和写入文件(fstream等)

    本文共321个字 xff0c 预计阅读时间需要1分钟 2019年7月非常忙 xff0c 这大概是这个月的第一篇吧 某高校机试需要从文件中读取数据并将数据写入到文件中 完成这一操作需要用到fstream模块 xff0c 网上一堆资料 xff0
  • 并查集应用——PAT甲级2019春季

    并查集适用问题举例 1 已知 xff0c 有n个人和m对好友关系 2 如果两个人是直接的或者间接的好友 xff08 好友的好友的好友 xff09 xff0c 那么他们属于一个集合 xff0c 就是一个朋友圈中 3 写出程序 xff0c 求这
  • 抽象工厂模式与单件模式C++混合实现

    抽象工厂 当每个抽象产品都有多于一个的具体子类的时候 xff0c 工厂角色怎么知道实例化哪一个子类呢 xff1f 比如每个抽象产品角色都有两个具体产品 抽象工厂模式提供两个具体工厂角色 xff0c 分别对应于这两个具体产品角色 xff0c
  • source命令自动运行terminal的指令

    source命令也称为 点命令 xff0c 也就是一个点符号 xff08 xff09 source命令通常用于重新执行刚修改的初始化文件 xff0c 使之立即生效 xff0c 而不必注销并重新登录 用法 xff1a source filen
  • 适配器模式C++实现

    本文共916个字 xff0c 预计阅读时间需要3分钟 简介 适配器模式 xff1a 将一个类的接口转换成客户希望的另一个接口 适配器模式让那些接口不兼容的类可以一起工作 适配器模式的别名为包装器 Wrapper 模式 xff0c 它既可以作
  • 装饰模式C++实现

    简介 动态地给一个对象添加一些额外的职责 就增加功能来说 xff0c 装饰模式比生成子类更为灵活 动机 有时我们希望给某个对象而不是整个类添加一些功能 使用继承机制是添加功能的一种有效途径 xff0c 但不够灵活 xff0c 用户不能控制对