c++ 设计模式23讲之享元模式

本文深入解析享元模式,一种利用共享技术减少大量细粒度对象的内存占用的设计模式。通过围棋棋子实例,展示了如何通过对象池实现对象复用,减少重复对象的创建,提高系统效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

享元模式

定义:

运用共享技术支持大量细粒度的复用

优点:

(1)减少内存中对象中的数量,使得相同或相似对象只保留一份

(2)外部状态相对独立不影响内部状态

缺点:

(1)系统变得复杂了,需要分离内部状态和外部状态

使用范围:

系统存在大量的相同相似对象,且这些对象可以组成对象池

如:围棋黑白棋子

结构:

flyweight_pattern:享元抽象类,棋子的基类

black_igo:黑子 ; white_igo:白子; coord:棋子位置(内部状态)

factory_flyweight_pattern:享元对象池

 

实现:

namespace structural_pattern
{
	class coord
	{
	public:
		coord(int x, int y) :x(x), y(y) {};
		int get_x() { return x; }
		int get_y() { return y; }
	private:
		int x;
		int y;
	};

	class flyweight_pattern
	{
	public:
		virtual void set_coord(int x, int y) = 0;
		virtual void disp() = 0;
	protected:
		std::vector<coord>vec_coord;
	};

	class black_igo : public flyweight_pattern
	{
		void set_coord(int x, int y) override
		{
			coord crd{ x,y };
			vec_coord.push_back(crd);
		}
		void disp() override
		{
			for each(auto itr in vec_coord)
			{
				std::cout << "black -- " << itr.get_x() << "  " << itr.get_y() << std::endl;
			}
		}
	};

	class white_igo : public flyweight_pattern
	{
		void set_coord(int x,int y) override
		{
			coord crd{ x,y };
			vec_coord.push_back(crd);
		}
		void disp() override
		{
			for each(auto itr in vec_coord)
			{
				std::cout << "white -- " << itr.get_x() << "  " << itr.get_y() << std::endl;
			}
		}
	};

	class factory_flyweight_pattern
	{
	public:
		factory_flyweight_pattern()
		{
			static flyweight_pattern* b = new black_igo();
			static flyweight_pattern* a = new white_igo();;
			flyweight.insert(std::pair<int, flyweight_pattern*>(1, b));
			flyweight.insert(std::pair<int, flyweight_pattern*>(2, a));
		}
		flyweight_pattern*get_igo(int key)
		{
			if (flyweight.find(key) != flyweight.end())
			{
				return flyweight.at(key);
			}
			throw new std::exception("no element");
		}
	private:
		std::map<int, flyweight_pattern*> flyweight;
	};
}

测试:

基于GoogleTest 的单元测试框架;框架可参考如下网址:

https://www.cnblogs.com/jycboy/p/gtest_catalog.html

using namespace structural_pattern;
TEST(test_flyweight_pattern_get_igo, success_add)
{
	factory_flyweight_pattern fac;
	fac.get_igo(1)->set_coord(1,2);
	fac.get_igo(1)->set_coord(2,4);
	fac.get_igo(1)->disp();
	fac.get_igo(2)->set_coord(1, 3);
	fac.get_igo(2)->set_coord(2, 6);
	fac.get_igo(2)->disp();
}

总结

(1)需要额外创建享元对象池类,通过map方式来保存享元对象

(2)通过key值获取真实的享元对象

(3)分离享元对象的内部和外部状态

(4)通过对象池方式实现对象复用,关注对象生命周期

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值