C++设计模式之享元模式

  • 使用场景
    当程序中使用到大量的类似对象实体时,大部分时候会出现内存不够用的情况。此时我们就可以考虑使用享元模式,一般在符合以下几点情况下来使用。1.是大量的对象 2.注重空间消耗而不是时间消耗 3.对象实体存在多种相同的内在属性。

  • 大概思想
    根据我所总结的就是将对象的大部分相同属性抽离出来实现一个共同属性结构,而其他的不共同属性保留下来让每个对象独立拥有。然后在使用的时候得先找到特有属性的共用属性结构在执行相应的操作。本质上就是时间换取空间。

  • 示例代码

#pragma once

#include <string>
#include <map>
#include <vector>

struct SharedState
{
	std::string _name;
	std::string _version;

	SharedState(const std::string& name, const std::string& version)
		:_name(name),_version(version)
	{}

	SharedState(const SharedState& ss) :_name(ss._name), _version(ss._version)
	{}

	friend void info(std::ostream& os, SharedState* ss);

};

void info(std::ostream& os, SharedState* ss)
{
	os << ss->_name << " " << ss->_version<<" ";
}

struct UniqueState
{
	std::string _color;
	int _size;

	UniqueState(const std::string& color, int size)
		:_color(color),_size(size)
	{}
};

class FlyWeight
{

public:
	FlyWeight(SharedState* sharedState):_sharedState(new SharedState(*sharedState))
	{}

	FlyWeight(const FlyWeight& flyWeight):_sharedState(new SharedState(*flyWeight._sharedState))
	{}

	~FlyWeight()
	{
		if (_sharedState)
			delete _sharedState;
	}

	void doOperation(const UniqueState& uniqueState)
	{
		if (_sharedState)
			info(std::cout, _sharedState);

		std::cout << uniqueState._color << " " << uniqueState._size << std::endl;;
	}

private:

	SharedState *_sharedState;
};


class FlyWeightFacotry
{
public:
	static FlyWeightFacotry& getInstance()
	{
		static FlyWeightFacotry factory;
		return factory;
	}

	void cache(const std::string& id, FlyWeight* flyWeight)
	{
		_flyWeightMap[id] = flyWeight;
	}

	FlyWeight* getFlyWeight(const std::string& id)

	{
		if (_flyWeightMap.find(id) != _flyWeightMap.end())
			return _flyWeightMap[id];
		else
			return nullptr;
	}

	~FlyWeightFacotry(){
		for (const auto& itr : _flyWeightMap)
		{
			if (itr.second)
				delete itr.second;
		}
	}

private:
	FlyWeightFacotry() = default;
	FlyWeightFacotry(const FlyWeightFacotry& factory) = default;
	FlyWeightFacotry& operator=(const FlyWeightFacotry& factory) = default;


	std::map<std::string, FlyWeight*> _flyWeightMap;
};

void flyWeightTest()
{
	SharedState* ss1 = new SharedState("Product1", "v1.0");
	FlyWeightFacotry::getInstance().cache("v1.0", new FlyWeight(ss1));
	SharedState* ss2 = new SharedState("Product1", "v2.0");
	FlyWeightFacotry::getInstance().cache("v2.0", new FlyWeight(ss2));

	std::vector<UniqueState> uniqueStateVec = {
		{"red", 1},{"green", 2},{"blue", 3},{"white", 4}
	};

	for (const UniqueState& us : uniqueStateVec)
	{
		FlyWeight* fly1 = FlyWeightFacotry::getInstance().getFlyWeight("v1.0");
		if (fly1) fly1->doOperation(us);
		
		FlyWeight* fly2 = FlyWeightFacotry::getInstance().getFlyWeight("v2.0");
		if (fly2) fly2->doOperation(us);
	}

	delete ss1;
	delete ss2;
}
  • 示例代码里面通过构造一个享元的工厂类缓存享元对象,通过对应的标识码来取得唯一的享元对象执行相应的私有操作。

关于工厂模式的相关介绍可以看下我之前的文章
C++模板实现工厂模式

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值