模式三:装饰者模式(Decorator Pattern)——对象的功能扩展

  • 装饰者模式

动态地将责任附加到对象上。若要扩展功能,装饰者提供比继承更有弹性的替代方案。

  • 应用分析——对象的功能扩展

对象的功能扩展,最简单的方式就是继承,但是几种不同的功能有不同的组合时,将会产生许许多多的类,这样不利于管理。采用装饰者模式,让装饰者与实际对象有相同的接口(继承同一抽象类),通过组合或委托的方式引用被装饰对象,然后对被装饰对象进行动态扩展,可以获得更大的灵活性。

  • 实例分析——星巴克有各种咖啡:HouseBlend、DarkRoast、Decaf、Espresso,客户购买时,可以要求加入各种调料,如:SteamedMilk、Soy、Mocha等等,星巴克会根据不同的调料进行收费,如果考虑用继承实现,那么类数将会爆发性增长,如果考虑使用标记变量,这可能是一个解决方案,但是不利于扩展,用装饰者模式,可以巧妙解决这一问题。

  • 代码分析

//Component.h
//公共接口
#ifndef COMPONENT_H
#define COMPONENT_H
#include <string>

class Component//被装饰对象和装饰者公共的接口
{
protected:
	std::string desc;
public:
	virtual std::string getdesc()
	{
		return desc;
	}
	virtual double cost()=0;
	virtual ~Component(){}
};

#endif


//ConcreteComponent.h
//被装饰者
#ifndef CONCRETECOMPONENT_H
#define CONCRETECOMPONENT_H

#include "Component.h"

//两种不同的咖啡
class HouseBlend:public Component
{
public:
	HouseBlend()
	{
		desc="HouseBlend";
	}
	double cost()
	{
		return 10.0;
	}
};

class DarkRoast:public Component
{
public:
	DarkRoast()
	{
		desc="DarkRoast";
	}
	double cost()
	{
		return 20.0;
	}
};


#endif


//Decorator.h
//装饰者
#ifndef DECORATOR_H
#define DECORATOR_H

#include "Component.h"

//两种调料
class Milk:public Component
{
private:
	Component *ptrCom;//被装饰者
public:
	Milk(Component *ptrCom)
	{
		this->ptrCom=ptrCom;
	}
	std::string getdesc()
	{
		return ptrCom->getdesc()+", Milk";
	}
	double cost()
	{
		return ptrCom->cost()+5.0;
	}
};

class Mocha:public Component
{
private:
	Component *ptrCom;
public:
	Mocha(Component *ptrCom)
	{
		this->ptrCom=ptrCom;
	}
	std::string getdesc()
	{
		return ptrCom->getdesc()+", Mocha";
	}
	double cost()
	{
		return ptrCom->cost()+15.0;
	}
};

#endif


//main.cpp
//测试程序

#include <iostream>
#include "Decorator.h"
#include "ConcreteComponent.h"
#define print(x) std::cout<<x->getdesc()<<": $"<<x->cost()<<std::endl

int main()
{
	Component *HB=new HouseBlend();
	print(HB);
	Component *DR=new DarkRoast();
	print(DR);

	Component *HB_Milk=new Milk(HB);
	print(HB_Milk);
	Component *HB_Milk_M=new Mocha(HB_Milk);
	print(HB_Milk_M);

	Component *DR_M=new Mocha(DR);
	print(DR_M);

	delete HB;
	delete HB_Milk;
	delete HB_Milk_M;
	delete DR;
	delete DR_M;

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值