Flyweight:享元模式

      享元模式可以避免大量且相似的开销。

      例如,停车场中有1000辆车,那么需要创建1000个对象。这样开销是非常大的。

      设这1000辆车中,Tesla有300辆,BMW有700辆。

以Tesla为例,300辆Tesla的基本属性都相同,仅仅是颜色不同,那么就考虑创建一个Tesla基础对象,然后300辆Tesla共享这一个对象,仅根据颜色不同进行各自的处理。

如,1号停车位的Tesla是红色,那么将Red这个外部状态传入给Tesla的共享对象,该对象将车的颜色更换为红色,然后绘制在停车位上;2号停车位的Tesla是蓝色,将Blue这个外部状态传入给Tesla的共享对象,该对象将车的颜色更换为蓝色。

BMW同理。

于是,1000辆车,只需要创建 2个对象。内部主体是共享的,仅需要根据传入的外部状态(非共享状态)进行一些处理。这样,会极大地节省开销。

      这就是享元模式。

      享元模式特征如下:

①   所有可共享的基础对象由一个享元工厂进行维护,即享元工厂维护一个享元池。如果池有所需要的基础对象,那么直接返回该基础对象;否则创建后放入池中,并返回

②   基础对象又称之为内部状态,是进行共享的部分;每个实际对象还有自己的特征,比如有的Tesla是红色,有的Tesla是蓝色,这些状态是不被共享的,是每个对象独有,称之为外部状态。外部状态由实际对象进行维护

 

1.    定义享元类及实际类

享元类即需要共享的类。该类定义了标准接口。同时该类具有一个内部状态变量。享元类对象可能有多个,不同的享元对象靠内部状态进行区分。

实际类是由享元类派生,该类是享元工厂所创建的实际类,含有对外部状态的处理函数。

class FlyWeight
{
public:
	virtual ~FlyWeight() {};
	virtual void Operation(const string& exState) {};
	string GetInsState() { return this->_insState; }
protected:
	//将构造函数设为protected,只有派生类可以访问
	FlyWeight(string insState) { this->_insState = insState; }
private:
	string _insState;
};

class ConFlyweight :public FlyWeight
{
public:
	//将参数传给基类的构造函数,令基类可以初始化
	ConFlyweight(string insState) :FlyWeight(insState) {};
	//接受外部状态,并处理
	void Operation(const string& exState) { this->_exState = exState; }
private:
	string _exState;
};

2.    定义享元工厂

享元工厂维护一个享元池。该享元池是一个vector。

当需要的指定内部状态的实际享元对象存在于享元池中时,直接将该对象取出即可;否则创建后加入享元池中,并取出。

class FlyWeightFactory
{
public:
	FlyWeight* GetFlyweight(const string& key)
	{
		vector<FlyWeight*>::iterator it = _fly.begin();
		for (; it != _fly.end(); it++)
		{
			if ((*it)->GetInsState() == key)
			{
				//已创建
				return *it;
			}
		}
		FlyWeight* fn = new ConFlyweight(key);
		_fly.push_back(fn);
		return fn;
	}
private:
	vector<FlyWeight*> _fly;
};

3.    用户使用

void main()
{
	FlyWeightFactory *fw = new FlyWeightFactory();
	FlyWeight* fw1 = fw->GetFlyweight("Tesla");
	FlyWeight* fw2 = fw->GetFlyweight("BMW");
	FlyWeight* fw3 = fw->GetFlyweight("Tesla");

	//根据外部状态进行处理
	fw1->Operation("Red");
	fw2->Operation("Green");
	fw3->Operation("Blue");
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值