装饰器模式
定义
允许向一个现有的对象添加新的功能,同时又不改变结构. 属于结构型模式,作为现有类的一个包装.
使用场景
扩展一个类的功能;
动增加功能,动态撤销.
基本思路
1、component组件 为抽象,具体组件(concrete_component),装饰器件(decorator)都需要继承
2、具体组件传入到 具体装饰器中 进行加工。
实例
一家饮料店出售(component)咖啡(concrete_component)、茶(concrete_component)等,另外可以根据客户需求添加不同的调料(decorator)比如摩卡(concrete_decorator)、奶昔(concrete_decorator)等,因此可能的饮料有摩卡咖啡、双倍奶昔咖啡等,在结算时就要同时计算调料和饮料的价格。
//beverage.h
#ifndef BEVERAGE_H
#define BEVERAGE_H
#include <string>
using namespace std;
class Bervage{
public:
virtual string getDescription(){
return description;
}
virtual double cost()=0;
protected:
string description;
};
#endif // BEVERAGE_H
//beverage_espresso.h
#ifndef BEVERAGE_ESPRESSO_H
#define BEVERAGE_ESPRESSO_H
#include "beverage.h"
/**** 具体的饮料类 ****/
class Espresso:public Bervage{
public:
Espresso(){
description = " Espresso ";
}
double cost(){
return 1.99;
}
};
#endif // BEVERAGE_ESPRESSO_H
//beverage_tea.h
#ifndef BEVERAGE_TEA_H
#define BEVERAGE_TEA_H
#include "beverage.h"
class Tea:public Bervage{
public:
Tea(){
description = " Tea ";
}
double cost(){
return 1.05;
}
};
#endif // BEVERAGE_TEA_H
//condiment_mocha.h
#ifndef CONDIMENT_MOCHA_H
#define CONDIMENT_MOCHA_H
#include "decorator_condiment.h"
/**** 具体的调料类 ****/
class Mocha:public CondimentDecorator{
public:
Mocha(Bervage *ptr){
pBervage = ptr;
}
string getDescription(){
return " Mocha "+pBervage->getDescription();
}
double cost(){
return 0.2+pBervage->cost();
}
};
#endif // CONDIMENT_MOCHA_H
//condiment_whip.h
#ifndef CONDIMENT_WHIP_H
#define CONDIMENT_WHIP_H
#include "decorator_condiment.h"
class Whip:public CondimentDecorator{
public:
Whip(Bervage *ptr){
pBervage = ptr;
}
string getDescription(){
return " Whip "+pBervage->getDescription();
}
double cost(){
return 0.5+pBervage->cost();
}
};
#endif // CONDIMENT_WHIP_H
//decorator_condiment.h
#ifndef DECORATOR_CONDIMENT_H
#define DECORATOR_CONDIMENT_H
#include "beverage.h"
class CondimentDecorator:public Bervage{
protected:
Bervage *pBervage;
};
#endif // DECORATOR_CONDIMENT_H
//main.cpp
#include <iostream>
#include "beverage_espresso.h"
#include "beverage_tea.h"
#include "condiment_mocha.h"
#include "condiment_whip.h"
using namespace std;
int main()
{
Espresso esp;
Mocha mocha(&esp);
cout<<mocha.cost()<<endl;
cout<<mocha.getDescription()<<endl;
Mocha dmocha(&mocha);
cout<<dmocha.cost()<<endl;
cout<<dmocha.getDescription()<<endl;
Whip wdmocha(&dmocha);
cout<<wdmocha.cost()<<endl;
cout<<wdmocha.getDescription()<<endl;
return 0;
}
输出:
2.19
Mocha Espresso
2.39
Mocha Mocha Espresso
2.89
Whip Mocha Mocha Espresso
总结
适配器模式/装饰模式/代理模式的区别?
适配器的特点在于兼容: 是将一个类(a)通过某种方式转换成另一个类(b);
装饰器模式特点在于增强: 在一个原有类(a)的基础之上增加了某些新的功能变成另一个类(b);
代理模式的特点在于隔离: 将一个类(a)转换成具体的操作类(b) .