结构型模式之装饰者模式

一、概述

1、装饰者模式:可以在不改变一个对象本身功能的基础上给对象增加额外的新行为

2、是一种用于替代继承的技术,它通过一种无须定义子类的方式给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系

3、引入装饰类,在装饰类中既可以调用待装饰的原有的方法还可以增加新的方法,以扩展原有类的功能

4、定义:动态地给一个对象增加一些额外的职责,就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案

二、装饰模式结构

装饰模式包含以下4个角色:

1、Component(抽象构架)

2、ConcreteComponent(具体构件类)

3、Decorator(抽象装饰类)

4、ConcreteDecorator(具体装饰类)

三、UML图

四、模式优点

1、对于扩展一个对象的功能,装饰模式比继承更加灵活,允许在运行时动态地增加、移除或组合不同的功能

2、符合单一职责原则,通过不同功能分散到不同的装饰者类中,每个装饰者类只负责一种功能,从而保持代码的清晰和模块化

3、避免类爆炸,与继承创建大量子类不同,装饰者模式通过组合装饰者实现功能扩展,从而减少了类的数量,降低了类的复杂性

五、模式缺点

1、使用装饰模式进行系统设计时将产生很多小对象,大量小对象的产生势必会占用更多的系统资源,在一定程度上影响程序的性能

2、使用装饰模式导致系统中出现大量的装饰者类,尤其是当有很多功能组合时,这可能会增加类的数量和复杂性

六、示例代码

#include <iostream>
using namespace std;

//抽象构件
class Beverge
{
public:
	virtual string getDescription() = 0;
	virtual double getCost() = 0;
};

//具体构件 混合咖啡类
class HouseBlend : public Beverge
{
public:
	string getDescription() override
	{
		return "混合咖啡";
	}
	double getCost() override
	{
		return 25.00;
	}
};

//具体构件 浓缩咖啡类
class Espresso : public Beverge
{
public:
	string getDescription() override
	{
		return "浓缩咖啡";
	}
	double getCost()
	{
		return 20.00;
	}
};

//抽象装饰者类 所有配料的抽象父亲
class Decorator : public Beverge
{
public:
	Decorator(Beverge *beverge) : m_beverge(beverge) {}

	string getDescription()
	{
		return m_beverge->getDescription();
	}
	double getCost()
	{
		return m_beverge->getCost();
	}
private:
	Beverge* m_beverge = nullptr;
};

//具体的装饰器类, 具体的配料--牛奶
class Milk : public Decorator
{
public:
	Milk(Beverge *beverge) : Decorator(beverge) {}

	string getDescription()
	{
		string decription = Decorator::getDescription();
		return decription + "牛奶";
	}
	double getCost()
	{
		double cost = Decorator::getCost();
		return cost + 2.0;
	}
};

class Mocha : public Decorator
{
public:
	Mocha(Beverge *beverge) : Decorator(beverge) {}

	string getDescription()
	{
		string description = Decorator::getDescription();
		return description + "摩卡";
	}
	double getCost()
	{
		double cost = Decorator::getCost();
		return cost + 3.0;
	}
};

int main()
{
	string description;
	double cost;

	Beverge* beverge = nullptr;
	beverge = new Espresso;
	description = beverge->getDescription();
	cost = beverge->getCost();

	cout << "coffe:" << description;
	cout << " 价格:" << cost;
	cout << endl << "---------------------" << endl;

	Beverge* beverge_mo = nullptr;
	beverge_mo = new Mocha(beverge);
	description = beverge_mo->getDescription();
	cost = beverge_mo->getCost();

	cout << "coffe:" << description;
	cout << " 价格:" << cost;
	cout << endl << "---------------------" << endl;

	Beverge* beverge_mi = nullptr;
	beverge_mi = new Milk(beverge_mo);
	description = beverge_mi->getDescription();
	cost = beverge_mi->getCost();

	cout << "coffe:" << description;
	cout << " 价格:" << cost;
	cout << endl << "---------------------" << endl;

	return 0;
}

七、运行结果

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值