设计模式之装饰者模式-有时候还是需要装饰一下自己才好!

一、装饰者模式的概念

装饰者模式又叫做包装模式,在不必改变原有类文件的情况下,它通过创建一个包装对象来不断地装饰原来的对象,来动态地扩展对象的功能,是继承关系的一个替换方案。

二、装饰者模式使用场景

1、当需要给一个对象扩展新的功能或者添加新的职责时可以使用装饰者模式。
2、当需要给一个对象动态的添加或者撤销功能时可以使用装饰者模式。
3、当一个类需要大量扩展时或者使用继承关系比较困难时,可以使用装饰者模式。

三、装饰者模式构建方法

1、抽象类

提供一个统一的抽象接口,以规范接收附加职责的对象,即具体对象。

2、具体类

定义实现抽象类的具体类,用来接收附加的职责或者功能。

3、装饰者类

包含一个构件对象的实例,并实现一个与抽象构件接口一致的接口。

4、具体装饰者类

负责给构件对象添加职责或者扩展功能。

四、装饰者模式的示例

// DecoratorPattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <string>
using namespace std;

// 抽象类(饮料)
class AbstractDrink
{
public:
	virtual string drinkName() = 0;

private:

};

// 具体类(奶茶)
class MilkTea : public AbstractDrink
{
public:
	string drinkName()
	{
		return "MilkTea";
	}

private:

};

// 装饰者类
class TasteDecorator : public AbstractDrink
{
public:
	//TasteDecorator() {}
	TasteDecorator(AbstractDrink *pDrink)
	{
		m_pDrink = pDrink;
	}
	string drinkName()
	{
		return m_pDrink->drinkName();
	}
	AbstractDrink *m_pDrink;
};

// 具体装饰者类
// 麦香味奶茶
class WheatTaste : public TasteDecorator
{
public:
	WheatTaste(AbstractDrink *pDrink) : TasteDecorator(pDrink) {}
	string drinkName()
	{
		return m_pDrink->drinkName() + "WheatTaste";
	}
};
// 苹果味奶茶
class AppleTaste : public TasteDecorator
{
public:
	AppleTaste(AbstractDrink *pDrink) : TasteDecorator(pDrink) {}
	
	string drinkName()
	{
		return m_pDrink->drinkName() + "AppleTaste";
	}
};
// 糖味奶茶
class SugarTaste : public TasteDecorator
{
public:
	SugarTaste(AbstractDrink *pDrink) : TasteDecorator(pDrink) {}

	string drinkName()
	{
		return m_pDrink->drinkName() + "SugarTaste";
	}
};

#define DELETE_PTR(p) {if(p!=nullptr){delete (p); (p)=nullptr;}}
int main()
{
	cout << "------装饰者模式------" << endl;
	AbstractDrink *pAbDrink = new MilkTea;
	cout << pAbDrink->drinkName() << endl;

	TasteDecorator *pWheatTaste = new WheatTaste(pAbDrink);
	cout << pWheatTaste->drinkName() << endl;

	TasteDecorator *pAppleTaste = new AppleTaste(pAbDrink);
	cout << pAppleTaste->drinkName() << endl;

	TasteDecorator *pSugarTaste = new SugarTaste(pAbDrink);
	cout << pSugarTaste->drinkName() << endl;
	DELETE_PTR(pSugarTaste);
	DELETE_PTR(pAppleTaste);
	DELETE_PTR(pWheatTaste);
	DELETE_PTR(pAbDrink);
    std::cout << "Hello World!\n";
	getchar();
}

运行结果:
在这里插入图片描述

五、装饰者模式的优缺点

优点:

1、可以动态地扩展对象,比继承更加的灵活。
2、通过不同的装饰可以实现不同的功能组合,创造不同的行为。

缺点:

1、比继承灵活却也更加的复杂。
2、过多的装饰会出现很多类,使代码的结构复杂。

能力有限,如有错误,多多指教。。。

发布了157 篇原创文章 · 获赞 135 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/toby54king/article/details/104366287