现在的位置: 首页 > 综合 > 正文

自己写的用c++实现的简单装饰者模式

2013年04月12日 ⁄ 综合 ⁄ 共 2834字 ⁄ 字号 评论关闭

在上传代码之前,先交代一下装饰模式的概念。。。

装饰模式(Decorator)可以在运行时动态地给对象增加功能。它也是对对象的包装,但与适配器模式不同的是它并没有改变被包装对象的接口,只是改变了它的能力范围,而且可以递归组合。

通过生成子类的方式也可以为对象增加功能,但它是静态的,而且大量的功能组合很容易产生“子类爆炸”现象。装饰模式可以动态、透明地给对象增加职责,并且在不需要的时候很容易去除,使用派生子类的方式无法达到这种灵活程度。

GOOD:当你向旧的类中添加新代码时,一般是为了添加核心职责或主要行为。而当需要加入的仅仅是一些特定情况下才会执行的特定的功能时(简单点就是不是核心应用的功能),就会增加类的复杂度。装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。


下面是主要实现,参照Head First的星巴兹咖啡案例实现。

#pragma once

#include <boost/format.hpp>
#include <iostream>

#include <string>

using namespace std;
class CBeverage
{
public:
	CBeverage(void);
	~CBeverage(void);
public:
	virtual int cost() = 0;
	virtual string getDescription()
	{
		return m_description;
	}
	virtual void setDescription(string strDescription)
	{
		m_description = strDescription;
	}
protected:
	string m_description;
};

class Blend: public CBeverage
{

public:
	int cost()
	{
		return 10;
	}
};

class DarkRoast: public CBeverage
{
public:
	int cost()
	{
		return 12;
	}
};

class Decorator: public CBeverage
{
public:
	//virtual string getDescription();
	int cost()
	{
		return m_observed_->cost() + 0;
	}
	void setObserver(boost::shared_ptr<CBeverage> observed) 
	{ 
		m_observed_ = observed; 
	}
protected:
	boost::shared_ptr<CBeverage> getobersver()
	{
		return m_observed_;
	}
private:
	boost::shared_ptr<CBeverage> m_observed_;
};

class Milk: public Decorator
{
public:
	string getDescription()
	{
		return getobersver()->getDescription() + ", Milk";
	}
	int cost()
	{
		return getobersver()->cost() + 2;//milk price:2
	}

};

class Mocha: public Decorator
{
public:
	string getDescription()
	{
		return getobersver()->getDescription() + ", Mocha";
	}
	int cost()
	{
		return getobersver()->cost() + 3;//mocha price: 3
	}
};

class Whip: public Decorator
{
public:
	string getDescription()
	{
		return getobersver()->getDescription() + ", Whip";
	}
	int cost()
	{
		return getobersver()->cost() + 4;//whip price:4
	}
};




int _tmain(int argc, _TCHAR* argv[])
{
	boost::shared_ptr<CBeverage> blendObserved(new Blend);
	blendObserved->setDescription("blend coffee");
	boost::shared_ptr<CBeverage> darkroastObers(new DarkRoast);
	darkroastObers->setDescription("DarkRoast coffee");

	boost::shared_ptr<Decorator> blendwithmilk(new Milk);
	blendwithmilk->setObserver(blendObserved);

	boost::shared_ptr<Decorator> blendwithmocha(new Mocha);
	blendwithmocha->setObserver(blendObserved);

	boost::shared_ptr<Decorator> darkroastwithmocha(new Mocha);
	darkroastwithmocha->setObserver(darkroastObers);

	boost::shared_ptr<Decorator> blendwithmochawhip(new Whip);
	blendwithmochawhip->setObserver(blendwithmocha);

	boost::shared_ptr<Decorator> blendwithmochawhipmilk(new Milk);
	blendwithmochawhipmilk->setObserver(blendwithmochawhip);


	cout<<blendwithmilk->cost()<<endl;
	cout<<blendwithmilk->getDescription()<<endl;
	cout<<blendwithmocha->cost()<<endl;
	cout<<blendwithmocha->getDescription()<<endl;
	cout<<darkroastwithmocha->cost()<<endl;
	cout<<darkroastwithmocha->getDescription()<<endl;
	cout<<blendwithmochawhip->cost()<<endl;
	cout<<blendwithmochawhip->getDescription()<<endl;
	cout<<blendwithmochawhipmilk->cost()<<endl;
	cout<<blendwithmochawhipmilk->getDescription()<<endl;

	return 0;
}

抱歉!评论已关闭.