设计模式--装饰模式

1. 定义

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

2. 作用

一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

3.场景举例

咖啡由咖啡豆加工而来,咖啡又扩展出了美式咖啡,拿铁,摩卡。而美式咖啡,拿铁,摩卡可以在咖啡豆的基础上做一些属性的装饰来完成,如他们的价格不一样,产地也不一样。为了避免继承自咖啡类,我们用装饰器模式来实现该需求。
设计模式--装饰模式_第1张图片

4. 代码实现举例

#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

你可能感兴趣的:(设计模式,设计模式,c++)