用C++跟你聊聊“装饰者模式”
时间:2022-07-23
本文章向大家介绍用C++跟你聊聊“装饰者模式”,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前方低能,大家坐好跟我说一声,我们准备发车了。
从穿衣服小游戏谈起
不知道大家有没有玩过那种游戏啊,开局给你一个不知道穿多少的人,然后你找一堆衣服给人家穿上,如果要穿的好一点那你还得花点钱啊。反正我是没玩过,我的童年游戏时光,都给了死神VS火影了。
如果现在要你来实现这么一个小游戏,你会怎么弄?很不巧的是,前面讲过的工厂模式和策略模式好像都用不了。有的人可能要说了啊,我直接一个函数,衣服套套套就完事儿了。那可不太行,需要有不同的穿搭。能穿,你还得能脱呢。
那怎么搞?小事情,今天我们聊聊“装饰者模式”。
装饰者模式
装饰者模式:动态的给一个对象添加一些额外的附加功能。拿上边那个栗子来说,给你一小姑娘/小伙子,要怎么穿是你的事儿。
如果看过了前面上一篇 - 依赖倒转原则
那我们就来看一下类图吧
上面那个栗子讲的通透了,那我们现在按着这个类图做一个手机装饰示例
代码示例
#include<iostream>
#include<string>
using namespace std;
class Phone
{
public:
Phone() {}
virtual ~Phone() {}
virtual void ShowDecorate() {}
};
//具体的手机类
class RongYao : public Phone
{
private:
string m_name; //手机名称
public:
RongYao(string name) : m_name(name) {}
~RongYao() {}
void ShowDecorate() { cout << m_name << "的装饰" << endl; }
};
//装饰主类
class DecoratorPhone : public Phone
{
private:
Phone* m_phone; //要装饰的手机
public:
DecoratorPhone(Phone* phone) : m_phone(phone) {}
virtual void ShowDecorate() { m_phone->ShowDecorate(); }
};
//具体的装饰类
class DecoratorPhoneA : public DecoratorPhone
{
public:
DecoratorPhoneA(Phone* phone) : DecoratorPhone(phone) {}
void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }
private:
void AddDecorate() { cout << "钢化玻璃屏" << endl; } //增加的装饰
};
class DecoratorPhoneB : public DecoratorPhone
{
public:
DecoratorPhoneB(Phone* phone) : DecoratorPhone(phone) {}
void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }
private:
void AddDecorate() { cout << "炫酷手机壳" << endl; } //增加的装饰
};
int main()
{
Phone* RongYao9 = new RongYao("HUAWEIRONGYAO");
Phone* dpa = new DecoratorPhoneA(RongYao9); //装饰,屏幕贴膜
Phone* dpb = new DecoratorPhoneB(dpa); //装饰,增加挂件
dpb->ShowDecorate();
delete dpa;
delete dpb;
delete RongYao9;
return 0;
}
装饰模式总结
上一个策略模式靠的是纯虚函数,这次,靠的是虚函数的使用。
装饰者模式是为已有实例动态的添加更多功能的一种方法。那么什么时候使用? 需要将类中的装饰部分分离出逻辑层的时候、需要给一个旧的类进行翻新的时候、对于一些特定情况下使用的特殊功能,可以使用装饰者模式套上去。
装饰者模式的一大有点就在于将类中的核心功能区与装饰层分离,这样可以简化原有的类。
不过有一点是要当心的:装饰者模式的装饰顺序是很重要的。
- Python基础01 Hello World!
- 剑指OFFER之从上往下打印二叉树(九度OJ1523)
- 给你的博客加上“Fork me on Github”彩带
- Android Studio添加PNG图片报错原因
- 剑指OFFER之包含min函数的栈(九度OJ1522)
- 使用VS2010开发Qt程序的一点经验
- 用Qt写软件系列五:一个安全防护软件的制作(3)
- 剑指OFFER之顺时针打印矩阵(九度OJ1391)
- 用Qt写软件系列五:一个安全防护软件的制作(2)
- 2018年值得关注的200场机器学习会议
- Linux开机启动(bootstrap)
- 剑指OFFER之树的子结构(九度OJ1520)
- 万物智联慧结成网:信息技术驱动物流产业转型升级
- 用Qt写软件系列五:一个安全防护软件的制作(1)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ABAP和Java的tag(marker) interface
- setTimeout 是到了xx ms 就执行吗,了解浏览器的 Event-Loop 机制
- 使用ABAP的RTTI和Java反射机制访问static private属性
- ABAP面试问题 - 不使用加减乘除等操作比较两个整数大小
- SAP订单上Shipping抬头和行项目字段的持久化实现原理
- SAP CRM订单模型CRMD_SHIPPING的单元测试方法
- 给SAP WebClient UI的表格行项目增添PDF预览功能
- 如何将ABAP透明表的内容导入PostgreSQL数据库
- 使用代理模式改善SAP UI5应用的图片加载体验
- 如何使用ABAP open SQL的locator
- dotnet 新 SDK Style 项目格式如何使用 InternalsVisibleToAttribute 功能
- WPF dotnet core 如何开启 Pointer 消息的支持
- web Storage的特点
- 四、实现跨域访问
- hadoop集群搭建