需求分析:需要对现有产品增加新的功能或美化其外观,房子装修、相片加相框。在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。
装饰模式:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)。
优点:
缺点:装增加了许多子类,如果过度使用会使程序变得很复杂。
核心思想:通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能。
主要角色:

具体案例:
小码路下班后与朋友一起去吃火锅,火锅基本套餐是200元,如果需要加配菜,另外收费。小码路喜欢吃海带,大虾。问最后总共花费类多少钱?
第一步:抽象构件角色
#pragma once
#include <iostream>
using namespace std;
//定义一个顶层接口
//定义总共花费钱和总共的菜品
class HuoGuo
{
public:
virtual float totalPrice()=0;
virtual string totalCai()=0;
};第二步:具体构件角色
//定义基类实现顶层接口
//将顶层接口进行赋值操作后,再次调用顶层接口里的方法
class HuoGuoCaiLei:public HuoGuo
{
public:
HuoGuo *huoguo;
public:
//将顶层接口以构造参数的方式传递进来
HuoGuoCaiLei(HuoGuo *hg)
{
this->huoguo=hg;
}
//重写顶层接口的方法,这里调用里面的方法
float totalPrice()
{
return huoguo->totalPrice();
}
string totalCai()
{
return huoguo->totalCai();
}
};第三步:抽象装饰角色
//接口和基类已封装完成,接下来定义上面提到的角色
//套餐价格200,是必点的,只需要实现顶层接口,复制操作就好
//添加的配菜必须依附这个
class TaoCanHuoGuo:public HuoGuo
{
public:
//套餐 200
float totalPrice()
{
return 200;
}
//核心配菜,简写套餐菜
string totalCai()
{
return "套餐菜";
}
};第四步:具体装饰角色
//此时可以添加额外的配菜了
//上面已经定义了添加配菜的基类,只要继承然后在子类设置附加菜品的价格就好
//添加海带
class HaiDai:public HuoGuoCaiLei
{
public:
HuoGuo *hg;
public:
HaiDai(HuoGuo *hg):HuoGuoCaiLei(hg)
{
}
//在父类的基础上增加海带的价格 30
float totalPrice()
{
return HuoGuoCaiLei::totalPrice()+30;
}
string totalCai()
{
return HuoGuoCaiLei::totalCai()+"添加了火锅配菜,";
}
};
//添加大虾
class DaXia:public HuoGuoCaiLei
{
public:
HuoGuo *hg;
public:
DaXia(HuoGuo *hg):HuoGuoCaiLei(hg)
{
}
//在父类的基础上增加海带的价格 60
float totalPrice()
{
return HuoGuoCaiLei::totalPrice()+60;
}
string totalCai()
{
return HuoGuoCaiLei::totalCai()+"添加了大虾配菜,";
}
};第五步:主函数
#include "m.h"
int main()
{
//实例化一个套餐火锅
HuoGuo *tchg=new TaoCanHuoGuo();
cout<<tchg->totalCai()<<" 总消费: "<<tchg->totalPrice()<<endl;
//添加海带
tchg=new HaiDai(tchg);
cout<<tchg->totalCai()<<" 总消费: "<<tchg->totalPrice()<<endl;
//添加大虾
tchg=new DaXia(tchg);
cout<<tchg->totalCai()<<" 总消费: "<<tchg->totalPrice()<<endl;
//再添加一份大虾
tchg=new DaXia(tchg);
cout<<tchg->totalCai()<<" 总消费: "<<tchg->totalPrice()<<endl;
return 0;
}结果显示:
