装饰器模式(Decorator) C++
装饰器模式是比较常用的一种设计模式,Python中就内置了对于装饰器的支持。
具体来说,装饰器模式是用来给对象增加某些特性或者对被装饰对象进行某些修改。
如上图所示,需要被装饰的对象在最上方,它自身可以有自己的实例,一般通过抽象类来实现(Java中也可以通过接口实现)。
右侧中间是一个装饰器类或者接口,其实内容与原对象基本一致,不过我们自定义的装饰器一般会继承这个装饰器基类。
最下层就是具体的装饰器了,可以看到,具体装饰器类中需要包含被装饰对象成员(也就是说,装饰器需要和被装饰对象有同样的子类),然后增加一些额外的操作。
下面的代码是一个买煎饼的例子,如我们生活中所见,可以选基础煎饼(鸡蛋煎饼,肉煎饼等),然后再额外加别的东西:
#include<iostream>
#include<string>
using namespace std; class Pancake//基类
{
public:
string description = "Basic Pancake";
virtual string getDescription(){ return description; }
virtual double cost() = ;
}; class CondimentDecorator :public Pancake//装饰器基类
{
public:
string getDescrition();
}; class MeatPancake :public Pancake//肉煎饼
{
public:
MeatPancake(){ description = "MeatPancake"; }
double cost(){ return ; }
};
class EggPancake :public Pancake//鸡蛋煎饼
{
public:
EggPancake(){ description = "EggPancake"; }
double cost(){ return ; }
}; class Egg :public CondimentDecorator//额外加鸡蛋
{
public:
Pancake* base;
string getDescription(){ return base->getDescription() + ", Egg"; }
Egg(Pancake* d){ base = d; }
double cost(){ return base->cost() + 1.5; }
};
class Potato :public CondimentDecorator//额外加土豆
{
public:
Pancake* base;
string getDescription(){ return base->getDescription() + ", Potato"; }
Potato(Pancake* d){ base = d; }
double cost(){ return base->cost() + ; }
};
class Bacon :public CondimentDecorator//额外加培根
{
public:
Pancake* base;
string getDescription(){ return base->getDescription() + ", Bacon"; }
Bacon(Pancake* d){ base = d; }
double cost(){ return base->cost() + ; }
}; int main()
{
Pancake* pan = new EggPancake();
pan = &Potato(pan);
pan = &Bacon(pan);
cout << pan->getDescription() << " $ : " << pan->cost() << endl;
system("pause");
return ;
}
可以看到,Pancake是煎饼的基类,这个基类因为定义了纯虚函数cost,所以不能被实例化。同样,装饰器基类CondimentDecorator也不能被实例化。
后面,EggPancake和MeatPancake是Pancake的派生类,是实际存在的类。
Egg、Bacon和Potato就是我们定义的装饰器对象,其中包含了Pancake的指针,可以对Pancake及其派生类进行操作。
运行代码的结果如下:
即我们选择了一个鸡蛋煎饼,然后额外加了土豆和培根,一共5+1+2=8块。
装饰器模式的优点:
1、可以轻松对已存在的对象进行修改和包装,在被装饰者的前面或者后面添加自己的行为,而无需修改原对象。
2、可以动态、不限量地进行装饰,可以更灵活地扩展功能。
相对地,装饰器模式有很明显的缺点:
1、会加入大量的小类,即使只添加一个功能,也要额外创建一个类,使得程序更复杂。
2、增加代码复杂度,使用装饰器模式不但需要实例化组件,还要把组件包装到装饰者中。
装饰器模式(Decorator) C++的更多相关文章
- 【PHP设计模式 09_ZhuangShiQi.php】装饰器模式 (decorator)
<?php /** * [装饰器模式 (decorator)] * 有时候发布一篇文章需要经过很多人手,层层处理 */ header("Content-type: text/html; ...
- 设计模式(八)装饰器模式Decorator(结构型)
设计模式(八)装饰器模式Decorator(结构型) 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法 ...
- 装饰器模式-Decorator(Java实现)
装饰器模式-Decorator(Java实现) 装饰器模式允许向一个现有的对象添加新的功能, 同时又不改变其结构. 其中 "现有对象"在本文中是StringDisplay类. 添加 ...
- 说说设计模式~装饰器模式(Decorator)~多功能消息组件的实现
返回目录 为何要设计多功能消息组件 之前写过一篇装饰器模式的文章,感觉不够深入,这次的例子是实现项目中遇到的,所以把它拿出来,再写写,之前也写过消息组件的文章,主要采用了策略模式实现的,即每个项目可以 ...
- 装饰器模式(Decorator)
转自http://blog.csdn.net/hust_is_lcd/article/details/7884320 1.认识装饰器模式 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象 ...
- 设计模式入门之装饰器模式Decorator
//装饰模式定义:动态地给一个对象加入一些额外的职责. //就添加功能来说.装饰模式比生成子类更为灵活 //这也提现了面向对象设计中的一条基本原则,即:尽量使用对象组合,而不是对象继承 //Compo ...
- 装饰器模式(Decorator)——深入理解与实战应用
本文为原创博文,转载请注明出处,侵权必究! 1.初识装饰器模式 装饰器模式,顾名思义,就是对已经存在的某些类进行装饰,以此来扩展一些功能.其结构图如下: Component为统一接口,也是装饰类和被装 ...
- 装饰器模式 Decorator 结构型 设计模式 (十)
引子 现实世界的装饰器模式 大家应该都吃过手抓饼,本文装饰器模式以手抓饼为模型展开简介 "老板,来一个手抓饼, 加个培根, 加个鸡蛋,多少钱?" 这句话会不 ...
- 设计模式学习心得<装饰器模式 Decorator>
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...
- 23种设计模式之装饰器模式(Decorator Pattern)
装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...
随机推荐
- BUPT复试专题—分数加法(2014网研)
题目描述 求2^-a + 2^-b,其中a和b均为正整数,结果用最简分数表示 输入 第一行为测试数据的组数T (1~400).请注意,任意两组测试数据之间相互独立的.每组测试数据一行,包含两个整数a和 ...
- 消息列队 分布式事务解办法 celery flower使用总结
前言 项目中有场景 需要用到 分布式事务业务,经过查下资料把学习相关笔记做记录方便他人或者自己后面查看. 场景 在网站A业务中有个操作 是 要在网站B中新建一台服务器跑业务.A中执行B中的接口创建服务 ...
- Android 最新控件 Toolbar
之前Android的ActionBar好像做项目从没用过.除了google自己,并没有多少人用,究其原因,主要是由于ActionBar不够灵活,不可以随心所欲的定制,后来Goole也发现了这一点,然后 ...
- 【试水CAS-4.0.3】第06节_CAS服务端配置HTTPS
完整版见https://jadyer.github.io/2012/05/30/tomcat-https/ /** * @see CAS服务端配置HTTPS * @see -------------- ...
- LeetCode——Reverse Integer
Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 Have you ...
- SpringBoot学习之启动报错【This application has no explicit mapping for /error.....】
今天做SpringBoot小例子,在请求controller层的时候出现如下问题. Whitelabel Error Page This application has no explicit map ...
- System V IPC相关函数
System V IPC 将一个已保存的路径名和一个整数标识符转换成一个key_t值,称为IPC键key_t:System V IPC(System V消息队列.System V信号量.System ...
- DTD笔记
DTD(Document Type Definition)文档类型定义: DTD被用于定义XML文档的结构,作为规范XML文档的一种内容模型,DTD在各领域已形成统一规范的文档. 在XML文档中使用D ...
- AliYunDun关闭
停止阿里云盾AliYunDun服务解决大量写磁盘问题-小内存ECS服务器 阿里云数据库在没备案,涉及大量IO操作时会自动启动阿里云盾这个服务,会导致服务器变得很卡 关闭服务: service aegi ...
- Codeforces Round #335 (Div. 2) 606B Testing Robots(模拟)
B. Testing Robots time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...