餐馆那些事之:Flyweight Pattern

1. 概述
在一些系统中,存在大量小粒度数据对象,这样带来很大的资源开销,如果这些对象存在可以共享的数据,可以通过多个对象共享数据,从而减少资源开销。例如游戏中的小怪,这些小怪的外观数据属于可共享数据,并不需要每个小怪的对象都保留外观数据。
Flyweight Pattern可以在避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作。
类图:
餐馆那些事之:Flyweight Pattern_第1张图片
Object:需要使用共享数据的对象
Flyweight:共享数据对象接口
ConcreteFlyweight:共享对象实例
Flyweight:共享对象工厂

2. 实例
菜单上的菜有以下属性:名字、菜系、价格,其中菜系是可以作为共享数据share的。
代码:
#include <iostream>
#include <map>
#include <string>
using namespace std;

//Flyweight
class Flyweight
{
public:
	virtual ~Flyweight()
	{
	}
	virtual void print() = 0;
};

//ConcreteFlyWeight
class StyleCookingFlyweight : public Flyweight
{
public:
	StyleCookingFlyweight(string s)
	{
		_name = s;
	}
	
	void print()
	{
		cout << "style: " << _name.c_str() << endl;
	}
 
private:
	string _name;
};

//FlyWeightFactory
class StyleCookingFlyweightFactory
{
public:
	virtual ~StyleCookingFlyweightFactory()
	{
		map<string, Flyweight*>::iterator it;
		for ( it = _style_cooking_map.begin(); it != _style_cooking_map.end(); it++ )  
		{
			if((*it).second)
			{
				delete (*it).second;
				(*it).second = NULL;
			}  
		}
	}
	
	int get_size()
	{
		return _style_cooking_map.size();
	}
	
	Flyweight* get_style_cooking(string key)
	{
		Flyweight *flyweight;
		map<string, Flyweight*>::iterator it;
		it = _style_cooking_map.find(key);
		
		// 存在则返回相应对象
		if(it != _style_cooking_map.end() )
		{
			flyweight = (*it).second;
		}
		else// 否则插入新对象
		{
			flyweight = new StyleCookingFlyweight(key);
			_style_cooking_map[key] = flyweight;
		}
	
		return flyweight;
	}
 
private:
	map<string, Flyweight*> _style_cooking_map;
};

//Object
class Food
{
public:
	Food(const char* s, int price, Flyweight* style_flyweight)
	{
		_name = s;
		_price = price;
		_style_flyweight = style_flyweight;
	}
	
	void report()
	{
		cout << "name: " << _name << endl;
		cout << "price: " << _price << endl;
		_style_flyweight->print();
		cout << endl; 
	}
	
private:
	//共享数据
	Flyweight* _style_flyweight;
	
	//菜名
	string _name;
	
	//菜价
	int _price;
};

//client
int main()
{
 StyleCookingFlyweightFactory style_factory;
 
 Food food1("Cold beef", 20, style_factory.get_style_cooking("Sichuan cuisine"));
 Food food2("White oil belly", 15, style_factory.get_style_cooking("Sichuan cuisine"));
 Food food3("Griddle skin beef", 30, style_factory.get_style_cooking("Hunan cuisine"));
 
 food1.report();
 food2.report();
 food3.report();
 
 cout << "Style Flyweight Factory size: " << style_factory.get_size() << endl;
 
 return 0;
}
输出:
name: Cold beef
price: 20
style: Sichuan cuisine

name: White oil belly
price: 15
style: Sichuan cuisine

name: Griddle skin beef
price: 30
style: Hunan cuisine

Style Flyweight Factory size: 2

你可能感兴趣的:(餐馆那些事之:Flyweight Pattern)