首页 > 代码库 > 享元模式

享元模式

     享元模式,运用共享技术有效的支持大量细粒度的对象。

       FlyweightFactory,一个享元工厂,用来创建并管理Flyweight对象。它主要是用来确保合理的共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。
       Flyweight类,所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。
       ConcreteFlyweight类,继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间。
       UnsharedConcreteFlyweight类,指那些不需要共享的Flyweight子类。因为Flyweight接口共享称为可能,但它并不强制共享。

内部状态与外部状态:
在享元对象内部并且不会随环境改变的共享部分,称为享元对象的内部状态,而随着环境改变而改变的、不可以共享的状态就是外部状态了。
享元模式可以避免大量相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是相同的,可以通过把那些参数移到类实例的外面,在方法调用时将它们传递进来,就可以通过共享大幅度的减少单个实例的数目。

应用场景:
如果一个应用程序中使用了大量的对象,而这些大量的对象都相似时,可以考虑使用享元模式。
实际应用中的有类似字符串常量等。

实例结构图中User类是一个外部状态,也就是各实例中不同的地方。

代码:
//Flyweight.h
#include "stdafx.h"
#include <iostream>
#include <map>
#include <string>
using namespace std;

class User
{
private :
        string m_name;
public :
       User( string name) :m_name( name){}
        string GetName()
       {
               return m_name;
       }
};

class Flyweight
{
public :
        virtual ~Flyweight(){}
        virtual void Operation( User* pUser) = 0;
};

class ConcreteFlyweight :public Flyweight
{
public :
        virtual void Operation( User* pUser)
       {
              cout << "具体Flyweight:" <<pUser ->GetName()<< endl;
       }
};

class UnsharedConcreteFlyweight :public Flyweight
{
public :
        virtual void Operation( User* pUser)
       {
              cout << "不共享的具体Flyweight:" << pUser->GetName() << endl;
       }
};


class FlyweightFactory
{
private :
        map< string, Flyweight*> Flyweights;
public :
       FlyweightFactory()
       {
               /*Flyweights.insert(make_pair("x", new ConcreteFlyweight()));
              Flyweights.insert(make_pair("y", new ConcreteFlyweight()));
              Flyweights.insert(make_pair("z", new ConcreteFlyweight()));*/
       }

        Flyweight* GetFlyweight( string key)
       {
               map< string, Flyweight*>:: iterator it = Flyweights.find( key);
               if (it == Flyweights.end()) //如果不存在,实例化一个
              {
                      ConcreteFlyweight * cf = new ConcreteFlyweight ();
                     Flyweights.insert(make_pair( key, cf));
                      return cf;
              }
               return it->second;
       }

        int GetCount()
       {
               return Flyweights.size();
       }
};
// FlyweightPattern.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Flyweight.h"

int _tmain (int argc , _TCHAR * argv [])
{
        FlyweightFactory * flyFactory = new FlyweightFactory ();

        Flyweight* fx = flyFactory->GetFlyweight( "x" );
       fx->Operation( new User( "小x" ));

        Flyweight* fy = flyFactory->GetFlyweight( "y" );
       fy->Operation( new User( "小y" ));

        Flyweight* fz = flyFactory->GetFlyweight( "z" );
       fz->Operation( new User( "小z" ));

        UnsharedConcreteFlyweight * uf = new UnsharedConcreteFlyweight ();
       uf->Operation( new User( "UnsharedConcreteFlyweight" ));

       cout << "共有" << flyFactory->GetCount() << "种类型" << endl;
       getchar();
        return 0;
}