#ifndef __FLYWEIGHT_H__
#define __FLYWEIGHT_H__
#include <string>
#include <map>
//【说明】
// 当系统中细粒度对象数量太多时,会导致运行代价过高,带来性能下降等问题。享元模式正是为解决这一类问题而诞生的。
// 在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池,用于存储具有相同内部状态的享元对象。
// 享元对象能做到共享的关键是区分内部状态和外部状态。
// 内部状态是存储在享元对象内部并且不会随环境改变而改变的状态,因此内部状态可以共享。
// 外部状态是随环境改变而改变的、不可以共享的状态。享元对象的外部状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。
//【定义】
// 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度对象的复用。
//【角色】
// Flyweight:具体的享元实现对象,必须是可共享的,需要封装享元对象的内部状态。
// FlyweightFactory:享元工厂,主要用来创建并管理共享的享元对象,并对外提供访问共享享元的接口。
//【意义】
// 享元模式的优点在于它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份。
// 享元模式的缺点是使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化,所以应当在多次重复使用享元对象时才值得使用享元模式。
//【示例】
//轻量级对象
class FlyWeight
{
public:
FlyWeight();
FlyWeight(std::string key);
virtual void Operate(int value); //value外部状态
private:
std::string m_key; //m_key内部状态
};
//享元工厂,管理和维护轻量级对象
class FlyWeightFactory
{
public:
FlyWeightFactory();
~FlyWeightFactory();
public:
FlyWeight * GetFlyWeight(std::string key);
private:
std::map<std::string, FlyWeight*> m_flymap;
};
void TestFlyWeight();
#endif
#include "Flyweight.h"
FlyWeight::FlyWeight()
{
}
FlyWeight::FlyWeight(std::string key) : m_key(key)
{
}
void FlyWeight::Operate(int value)
{
printf("ConcreteFlyWeight m_key[%s], value[%d]\n", m_key.c_str(), value);
}
FlyWeight * FlyWeightFactory::GetFlyWeight(std::string key)
{
std::map<std::string, FlyWeight*>::iterator it = m_flymap.find(key);
if (it != m_flymap.end())
{
return it->second;
}
FlyWeight * fly = new FlyWeight(key);
m_flymap.insert(std::map<std::string, FlyWeight*>::value_type(key,fly));
return fly;
}
FlyWeightFactory::FlyWeightFactory()
{
}
FlyWeightFactory::~FlyWeightFactory()
{
std::map<std::string, FlyWeight*>::iterator iter;
for (iter = m_flymap.begin(); iter != m_flymap.end(); iter++)
{
if (iter->second != NULL)
{
delete iter->second;
iter->second = NULL;
}
}
}
void TestFlyWeight()
{
FlyWeightFactory * flyFactory = new FlyWeightFactory();
FlyWeight * fly1 = flyFactory->GetFlyWeight("X");
FlyWeight * fly2 = flyFactory->GetFlyWeight("Y");
FlyWeight * fly3 = flyFactory->GetFlyWeight("X");
FlyWeight * fly4 = flyFactory->GetFlyWeight("X");
fly1->Operate(11);
fly4->Operate(15);
delete flyFactory;
}