装饰者模式
来源:互联网 发布:中国森林覆盖率 知乎 编辑:程序博客网 时间:2024/04/30 09:28
请先理解为什么要引入装饰者模式?
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
我们以饮料为主体,然后在运行时以调料来装饰饮料。
注意:
1.装饰者和被装饰者有相同的超类型。
2.可以用一个或多个装饰者包装一个对象。
3.在任何需要原始对象(被包装)的场合,可以用装饰过的对象代替它。
4.装饰者可以在所委托被装饰者的行为之前与(或)之后,加上自己的行为,已达到特定的目的。
5.对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。
注意这句话:
每个包装者都有一个(包装一个)组件,也就是说,装饰者有一个实例变量以保存某个Component的引用。
下面来看饮料对应的类图:
注意:
将装饰者与组件组合时,就是在加入新的行为。所得到的新行为,并不是继承自超类,而是有组合对象得来的。
Beverage和CondimentDecorator都是抽象类。
下面是调料(装饰者)的代码:
class Mocha :public CondimentDecorator{private:Beverage beverage; //用一个实例变量记录饮料,也就是被装饰者public:Mocha(Beverage beverage) //把饮料当做构造器的参数{this.beverage = beverage;}string getDescription(){return beverage.getDescription() + ", Mocha"; //这就是“委托”达到继承效果}double cost(){return 0.20 + beverage.cost(); //首先把调用委托给被装饰对象,然后再加上Mocha的价钱}};
下面是整体实现,但是存在内存泄漏,可以考虑用智能指针。
#include <iostream>#include <vector>#include <string>#include <list>using namespace std;/*饮料(beverage)抽象类*/class Beverage{protected:string description = "Unknown Beverage";public:virtual string getDescription(){ return description; }virtual double cost() = 0;};/*浓缩咖啡(espresso)类*/class Espresso :public Beverage {public:Espresso(){ description = "Espresso"; }double cost(){ return 1.99; }};/*House Blend Coffee类*/class HouseBlend :public Beverage{public:HouseBlend(){ description = "House Blend Coffee"; }double cost(){ return .89; }};/*DaikRoast 类*/class DaikRoast :public Beverage{public:DaikRoast(){ description = "Daik Roast Coffee"; }double cost(){ return 1.89; }};/*Decat 类*/class Decat :public Beverage{public:Decat(){ description = "Decat Coffee"; }double cost(){ return .99; }};/*调料(condiment)抽象类,也即装饰者类*/class CondimentDecorator :public Beverage{//装饰者和被装饰者“类型匹配”,所以public继承virtual string getDescription() = 0;};/*注意下面的实现,就用到了委托的办法,先委托给被装饰对象,计算结果后再加上装饰者的*/class Mocha :public CondimentDecorator{private:Beverage *beverage; //has apublic:Mocha(Beverage *_beverage) :beverage(_beverage){}string getDescription(){ return beverage->getDescription() + ", Mocha"; }double cost(){ return .20 + beverage->cost(); }};class Whip :public CondimentDecorator{private:Beverage *beverage; //has apublic:Whip(Beverage *_beverage) :beverage(_beverage){}string getDescription(){ return beverage->getDescription() + ", Whip"; }double cost(){ return .50 + beverage->cost(); }};class Soy :public CondimentDecorator{private:Beverage *beverage; //has apublic:Soy(Beverage *_beverage) :beverage(_beverage){}string getDescription(){ return beverage->getDescription() + ", Soy"; }double cost(){ return .30 + beverage->cost(); }};int main(void){ Beverage *beverage = new Espresso();cout << beverage->getDescription() << " $" << beverage->cost() << endl;Beverage *beverage2 = new Espresso();beverage2 = new Mocha(beverage2);beverage2 = new Mocha(beverage2);beverage2 = new Whip(beverage2);cout << beverage2->getDescription() << " $" << beverage2->cost() << endl;Beverage *beverage3 = new Espresso();beverage3 = new Soy(beverage3);beverage3 = new Mocha(beverage3);beverage3 = new Whip(beverage3);cout << beverage3->getDescription() << " $" << beverage3->cost() << endl;delete beverage;delete beverage2;delete beverage3;_CrtDumpMemoryLeaks(); //检测是否有内存泄漏return 0;}
0 0
- 装饰者模式(Derector)
- 装饰者模式
- Decorator 装饰者模式
- 装饰者设计模式
- 装饰者模式
- 装饰者模式
- 装饰者模式
- 装饰者模式(Decorator)
- 装饰者模式
- 装饰者模式
- 装饰者模式
- 装饰者模式 DecoratorPattern
- 设计模式 - 装饰者
- 装饰者模式
- 装饰者模式
- 装饰者模式 - 2
- 装饰者模式
- 装饰者模式
- javascript jsp登陆界面
- AndroidManifest.xml配置文件详解
- Android小问题:android studio怎么查看数字签名 sha1(集成百度地图)
- 欢迎使用CSDN-markdown编辑器
- 网络7层协议简单总结
- 装饰者模式
- Linux字符设备驱动和杂项设备驱动对比
- Android Studio 图片资源引用杂谈
- variadic functions
- COM组件 IDispatch 及双接口的调用
- Hadoop 2.0 – HA功能中ZKFC对NN状态的控制
- 从 0 到 1:微信后台系统的演进之路zt
- websphere建立概要时指定端口号
- arp包win32下链接出错问题