享元模式

来源:互联网 发布:python基础教程在线 编辑:程序博客网 时间:2024/06/14 00:26
首先来看一个情景,我们在写文档的时候,有很多的字,但是这些字难道真的一个一个独立的对像吗?如果真的是一个一个独立真实的对象,那么内存就会爆掉的。大家可能听说过字库,我们看到的字都是字库里面的,每个显示的字都是字库里面的,每个字在字库里只会有一个对象,那么就意味着文档里的相同的字都会指向同一个对象,这样的好处是什么呢?可以节省大量的资源。

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


Flyweight类,它是所有具体享元类的父类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。
ConcreteFlyweight是继承Flyweight子类或实现Flyweight接口,并为内部状态增加存储空间。
UnsharedFlyweight是指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但它并不强制共享。
FlyweightFactory,是一个享元工厂,它主要是用来确保合理的共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。
注意在这种模式中,客户端不在直接和元素交互,而是和工厂交互,即取字符的时候不是new一个字符出来,而是通过工厂里面的接口获取。
应用场景:如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时应该考虑使用该模式;还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以使用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

#include<iostream>#include<string>#include<map>using namespace std;//模拟一个0-9数字字符库,class Flyweight//所有字符的基类{public:virtual void Operation() = 0;//对字符的操作,至少要显示字符virtual ~Flyweight(){}};class ConcreteFlyweight : public Flyweight //具体的字符,0,1,2,3,4,5.。。。。{private:char ch;public:ConcreteFlyweight(char _ch) :ch(_ch){}void Operation(){cout << "char=" << ch << endl;}};class FlyweightFactory//一个字符生产工厂,取字符的地方{private:map<char, Flyweight*>m;//每一个字符都有唯一的对象public:FlyweightFactory(){m.insert(make_pair('0', new ConcreteFlyweight('0')));//一开支字符库里面的字符m.insert(make_pair('1', new ConcreteFlyweight('1')));m.insert(make_pair('2', new ConcreteFlyweight('2')));m.insert(make_pair('3', new ConcreteFlyweight('3')));}Flyweight* GetFlyweight(char key)//获取字符{if (m.find(key) == m.end())//字符库里没有这个字符,就添加一个字符{m.insert(make_pair(key, new ConcreteFlyweight(key)));}return m[key];}int FlyweightCount()//字符数量的大小{return m.size();}~FlyweightFactory(){map<char, Flyweight*>::iterator p = m.begin();for (; p != m.end(); p++){Flyweight *fp = p->second;delete fp;}}};int main(){FlyweightFactory* f = new FlyweightFactory();Flyweight* f0 = f->GetFlyweight('0');f0->Operation();Flyweight* f1 = f->GetFlyweight('1');f1->Operation();Flyweight* f2 = f->GetFlyweight('2');f2->Operation();Flyweight* f5 = f->GetFlyweight('5');f5->Operation();Flyweight* f8 = f->GetFlyweight('8');f8->Operation();Flyweight* f00 = f->GetFlyweight('0');//虽然又需要一个0,但是两个0共享一个对象f00->Operation();cout << "字符库大小:" << f->FlyweightCount() << endl;delete f;}


原创粉丝点击