装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
咖啡由咖啡豆加工而来,咖啡又扩展出了美式咖啡,拿铁,摩卡。而美式咖啡,拿铁,摩卡可以在咖啡豆的基础上做一些属性的装饰来完成,如他们的价格不一样,产地也不一样。为了避免继承自咖啡类,我们用装饰器模式来实现该需求。
#include
#include
/**
* @brief 简单概述
* @brief 咖啡豆抽象基类
*/
class CoffeeBean
{
public:
virtual void ShowCoffeeName() = 0;
virtual void ShowPrice() = 0;
public:
std::string m_sCoffeeName;
int m_iPrice;
};
/**
* @brief 简单概述
* @brief 咖啡类
*/
class Coffee:public CoffeeBean
{
public:
Coffee(std::string name,int price)
{
m_sCoffeeName = name;
m_iPrice = price;
}
~Coffee() {}
void ShowCoffeeName()
{
std::cout << "CoffeeBean name:" << m_sCoffeeName << std::endl;
}
void ShowPrice()
{
std::cout << "CoffeeBean Price:" << m_iPrice << std::endl;
}
};
/**
* @brief 简单概述
* @brief 扩展类咖啡
*/
class ExtendCoffee :public CoffeeBean
{
public:
ExtendCoffee(CoffeeBean* pBean)
{
m_pBean = pBean;
}
~ExtendCoffee(){}
virtual void ShowCoffeeName() = 0;
virtual void ShowPrice() = 0;
protected:
CoffeeBean* m_pBean;
};
/**
* @brief 简单概述
* @brief 美式咖啡
*/
class Americano :public ExtendCoffee
{
public:
Americano(CoffeeBean* pBean):ExtendCoffee(pBean){}
~Americano() {}
void ShowCoffeeName()
{
std::cout << "I am Americano Coffee,Coffee name:" << m_pBean->m_sCoffeeName + " from American" << std::endl;
}
void ShowPrice()
{
m_pBean->m_iPrice = 48;
std::cout << "Americano Coffee price:" << m_pBean->m_iPrice << std::endl;
}
};
/**
* @brief 简单概述
* @brief 拿铁
*/
class Latte :public ExtendCoffee
{
public:
Latte(CoffeeBean* pBean) :ExtendCoffee(pBean) {}
~Latte() {}
void ShowCoffeeName()
{
std::cout << "I am Latte Coffee,Coffee name:" << m_pBean->m_sCoffeeName + " from Italy" << std::endl;
}
void ShowPrice()
{
m_pBean->m_iPrice = 58;
std::cout << "Latte Coffee price:" << m_pBean->m_iPrice << std::endl;
}
};
/**
* @brief 简单概述
* @brief 摩卡
*/
class Mocha :public ExtendCoffee
{
public:
Mocha(CoffeeBean* pBean) :ExtendCoffee(pBean) {}
~Mocha() {}
void ShowCoffeeName()
{
std::cout << "I am Mocha Coffee,Coffee name:" << m_pBean->m_sCoffeeName + " from Franch" << std::endl;
}
void ShowPrice()
{
m_pBean->m_iPrice = 68;
std::cout << "Mocha Coffee price:" << m_pBean->m_iPrice << std::endl;
}
};
int main(){
Coffee* mCoffee = new Coffee("CoffeeBean",200);
mCoffee->ShowCoffeeName();
mCoffee->ShowPrice();
Americano* mAmCoffee = new Americano(mCoffee);
mAmCoffee->ShowCoffeeName();
mAmCoffee->ShowPrice();
Latte* mLatterCoffee = new Latte(mCoffee);
mLatterCoffee->ShowCoffeeName();
mLatterCoffee->ShowPrice();
Mocha* mMochaCoffee = new Mocha(mCoffee);
mMochaCoffee->ShowCoffeeName();
mMochaCoffee->ShowPrice();
std::cout << std::endl;
}
https://zhuanlan.zhihu.com/p/270199941