享元模式-C++实现

享元模式(FlyWeight Pattern)是一种结构型设计模式,旨在减少对象创建的数量,节省内存和提高性能。

在某些情况下,一个项目里可能需要创建大量相似的对象,这样对象的一部分是共享的(相同的),还有一部分是个性化(不同的)。享元模式通过共享相同数据的方式,减少了对象的创建,从而减少了内存的占用。

举例:
比如说在一个文本编辑器里,需要大量相同的文本内容,但是相同的文本内容又有一些区别,比如字体大小、字体颜色。这种时候就可以使用享元模式创建大量的相似对象,节省内存和提高性能。

在这个例子中,文本内容减少共享数据,字体大小、字体颜色就是个性化定制,也就是外部数据。

享元模式有两个角色:对象、创建对象的工厂。

#pragma once

#include 
#include 
#include 
#include 

// 文本对象
class Text
{
public:
	Text(const std::string& _content)
		: content_(_content)
	{}

	// 获取文本内容
	void GetContent()
	{
		std::cout << color_ << "的" << content_ << std::endl;
	}

	// 个性化定制 设置文本内容的颜色
	void SetContentColor(const std::string& _color)
	{
		color_ = _color;
	}

private:
	std::string content_;

	std::string color_;
};

// 文本工厂
class TextFactory
{
public:

	static std::shared_ptr<Text> GetText(const std::string& _text)
	{
		if (text_pool_.find(_text) == text_pool_.end())
			text_pool_[_text] = std::make_shared<Text>(_text);

		return text_pool_[_text];
	}

private:

	static std::unordered_map<std::string, std::shared_ptr<Text>> text_pool_;
};

std::unordered_map<std::string, std::shared_ptr<Text>> TextFactory::text_pool_;

测试:

void TestFlyWeight()
{
	// 创建工厂
	std::shared_ptr<TextFactory> text_factory = std::make_shared<TextFactory>();

	// 创建文本对象
	std::shared_ptr<Text> text1 = text_factory->GetText("hello");
	// 个性化定制
	text1->SetContentColor("红色");
	// 使用
	text1->GetContent();

	std::shared_ptr<Text> text2 = text_factory->GetText("world");
	text2->SetContentColor("绿色");
	text2->GetContent();

	std::shared_ptr<Text> text3 = text_factory->GetText("hello");
	text3->SetContentColor("黄色");
	text3->GetContent();

	// 检查文本对象是否相同
	std::cout << std::boolalpha;
	std::cout << (text1 == text2) << std::endl;  // false
	std::cout << (text1 == text3) << std::endl;  // true
}

输出:

红色的hello
绿色的world
黄色的hello
false
true

我们可以看到text1和text2是同一个对象,但是通过个性化定制我们就可以使用不同颜色的相同文本内容。

文本工厂其实可以写成单例模式,这样我们不管在什么时候获取到文本对象都是同一个对象。

优点:

1、减少内存使用:通过共享相似对象的相同内部状态来减少内存消耗,相同的对象在内存中只创建一次,通过共享来重用。

2、提高性能:由于重复的对象被共享,可以减少创建和销毁对象的开销,提高性能。

缺点:

1、共享状态的限制:由于具有相同内部状态的对象是共享的,所以一个对象修改了自己的外部状态之后,会影响到其他的共享对象。比如上述例子中我们把text1的颜色设置黄色,如果我们不设置text3的颜色,则它的颜色也是黄色。

2、引入共享管理:由于享元模式引入了共享对象的管理机制,就需要创建一个享元工厂或缓存来管理共享对象的创建和存取,增加了系统的复杂性。

3、某些情况下的性能问题:当需要频繁地创建和销毁共享对象时,或者共享对象的数量非常庞大时,共享对象管理的开销可能会超过由于共享而节约的时间。

你可能感兴趣的:(设计模式,c++,享元模式)