zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C++设计模式---享元模式----浪费可耻,节俭光荣

C++模式设计模式 --- ---- 享元 浪费
2023-09-14 08:59:42 时间

一个软件系统在运行时产生的对象数量太多,将导致运行代价过高,带来系统性能下降等问题。

想想我们编辑文档用的word,文档里文字很多都是重复的,我们不可能为每一个出现的汉字都创建独立的空间,这样代价太大,那么我们如何去避免系统中出现大量相同或相似的对象,同时又不影响客户端程序通过面向对象的方式对这些对象进行操作?

享元模式正为解决这一类问题而诞生。享元模式通过共享技术实现相同或相似对象的重用,在逻辑上每一个出现的字符都有一个对象与之对应,然而在物理上它们却共享同一个享元对象,这个对象可以出现在一个字符串的不同地方,相同的字符对象都指向同一个实例,在享元模式中,存储这些共享实例对象的地方称为享元池(Flyweight Pool)。我们可以针对每一个不同的字符创建一个享元对象,将其放在享元池中,需要时再从享元池取出。 实现策略
1)Flyweight模式中,最重要的是将对象分解成intrinsic和extrinsic两部分。
2)内部状态:在享元对象内部并且不会随环境改变而改变的共享部分,可以称为是享元对象的内部状态
3)外部状态:而随环境改变而改变的,取决于应用环境,或是实时数据,这些不可以共享的东西就是外部状态了。
4)内部状态和外部状态之间的区别:
在Flyweight模式应用中,通常修改的是外部状态属性,而内部状态属性一般都是用于参考或计算时引用。
Flyweight执行时所需的状态必定是内部的或外部的。内部状态存储于ConcreteFlyweight对象之中;而外部状态则由Client对象存储或计算。当用户调用Flyweight对象的操作时,将该状态传递给它。 以文字处理软件为例:
内部状态存储于flyweight中,它包含了独立于flyweight场景的信息,这些信息使得flyweight可以被共享。如字符代码,字符大小……
外部状态取决于flyweight场景,并根据场景而变化,因此不可共享。用户对象负责在必要的时候将外部状态传递给flyweight,如字符位置,字符颜色…… 组成 ①Flyweight: 享元类的基类,定义一个接口,通过这个接口Flyweight可以接受并作用于外部状态。 ②ConcreteFlyweight:
实现Flyweight接口, 并为内部状态( 如果有的话) 增加存储空间。ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的(intrinsic);即,它必须独立于ConcreteFlyweight对象的场景。
③UnsharedConcreteFlyweight:
并非所有的Flyweight子类都需要被共享。Flyweight接口使共享成为可能,但它并不强制共享。在Flyweight对象结构的某些层次,④UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。

1) 创建并管理Flyweight对象。
2)确保合理地共享Flyweight。当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)
⑥Client 1)维持一个对Flyweight的引用。
2)计算或存储一个(多个)Flyweight的外部状态。

    //操作外部状态extrinsicState       virtual void Operation(const string  extrinsicState) = 0;       string GetIntrinsicState( );       virtual ~Flyweight( );   protected:       Flyweight(string intrinsicState);   private:              // 内部状态,也可以放在ConcreteFlyweight中       string _intrinsicState;   ConcreteFlyweight:实现Flyweight接口, 并为内部状态( 如果有的话) 增加存储空间。  ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的(intrinsic);  即,它必须独立于ConcreteFlyweight对象的场景。  class ConcreteFlyweight : public Flyweight   public:       //实现接口函数       virtual void Operation(const string  extrinsicState);       ConcreteFlyweight(string intrinsicState);       ~ConcreteFlyweight();   UnsharedConcreteFlyweight:并非所有的Flyweight子类都需要被共享。  Flyweight接口使共享成为可能,但它并不强制共享。  在Flyweight对象结构的某些层次,  UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。  class UnsharedConcreteFlyweight:public Flyweight   public:       virtual void Operation(const string  extrinsicState);       UnsharedConcreteFlyweight(string intrinsicState);       ~UnsharedConcreteFlyweight();   class FlyweightFactory   public:       FlyweightFactory();       ~FlyweightFactory();       //获得一个请求的Flyweight对象       Flyweight* GetFlyweight(string key);       //获取容器中存储的对象数量       void GetFlyweightCount();   protected:   private:       //保存内部状态对象的容器       vector Flyweight*  m_vecFly;   #endif  
ConcreteFlyweight:实现Flyweight接口, 并为内部状态( 如果有的话) 增加存储空间。 ConcreteFlyweight对象必须是可共享的。它所存储的状态必须是内部的(intrinsic); 即,它必须独立于ConcreteFlyweight对象的场景。 class ConcreteFlyweight : public Flyweight public: //实现接口函数 virtual void Operation(const string extrinsicState); ConcreteFlyweight(string intrinsicState); ~ConcreteFlyweight();
UnsharedConcreteFlyweight:并非所有的Flyweight子类都需要被共享。 Flyweight接口使共享成为可能,但它并不强制共享。 在Flyweight对象结构的某些层次, UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。 class UnsharedConcreteFlyweight:public Flyweight public: virtual void Operation(const string extrinsicState); UnsharedConcreteFlyweight(string intrinsicState); ~UnsharedConcreteFlyweight(); class FlyweightFactory public: FlyweightFactory(); ~FlyweightFactory(); //获得一个请求的Flyweight对象 Flyweight* GetFlyweight(string key); //获取容器中存储的对象数量 void GetFlyweightCount(); protected: private: //保存内部状态对象的容器 vector Flyweight* m_vecFly; #endif // Flyweight.cpp

ConcreteFlyweight::ConcreteFlyweight(string intrinsicState):Flyweight(intrinsicState)   ConcreteFlyweight::~ConcreteFlyweight()   void ConcreteFlyweight::Operation(const string  extrinsicState)       cout   this- GetIntrinsicState()   endl;       cout   extrinsicState   endl;   UnsharedConcreteFlyweight::UnsharedConcreteFlyweight(string intrinsicState):Flyweight(intrinsicState)   UnsharedConcreteFlyweight::~UnsharedConcreteFlyweight()   void UnsharedConcreteFlyweight::Operation(const string  extrinsicState)       cout   "extrinsicState"   endl;   FlyweightFactory::FlyweightFactory()   FlyweightFactory::~FlyweightFactory()   //若该对象已存在,直接返回,否则新建一个对象,存入容器中,再返回   Flyweight* FlyweightFactory::GetFlyweight(string key)       vector Flyweight* ::iterator iter = this- m_vecFly.begin();       for(;iter!= this- m_vecFly.end();iter++)       {           if((*iter)- GetIntrinsicState() == key)           {               return *iter;           }       }       Flyweight* fly = new ConcreteFlyweight(key);       this- m_vecFly.push_back(fly);       return fly;   void FlyweightFactory::GetFlyweightCount()       cout   this- m_vecFly.size()   endl;  
UnsharedConcreteFlyweight::UnsharedConcreteFlyweight(string intrinsicState):Flyweight(intrinsicState) UnsharedConcreteFlyweight::~UnsharedConcreteFlyweight() void UnsharedConcreteFlyweight::Operation(const string extrinsicState) cout "extrinsicState" endl; FlyweightFactory::FlyweightFactory() FlyweightFactory::~FlyweightFactory() //若该对象已存在,直接返回,否则新建一个对象,存入容器中,再返回 Flyweight* FlyweightFactory::GetFlyweight(string key) vector Flyweight* ::iterator iter = this- m_vecFly.begin(); for(;iter!= this- m_vecFly.end();iter++) if((*iter)- GetIntrinsicState() == key) return *iter; Flyweight* fly = new ConcreteFlyweight(key); this- m_vecFly.push_back(fly); return fly; void FlyweightFactory::GetFlyweightCount() cout this- m_vecFly.size() endl; } main.cpp
    //向工厂申请一个Flyweight对象,且该对象的内部状态值为“hello”       Flyweight* fly = fc- GetFlyweight("hello");       Flyweight* fly1 = fc- GetFlyweight("hello");       //应用外部状态       fly- Operation(extrinsicState);       fc- GetFlyweightCount();       return 0;  
//向工厂申请一个Flyweight对象,且该对象的内部状态值为“hello” Flyweight* fly = fc- GetFlyweight("hello"); Flyweight* fly1 = fc- GetFlyweight("hello"); //应用外部状态 fly- Operation(extrinsicState); fc- GetFlyweightCount(); return 0; } Makefile
另外一个围棋的例子: http://blog.csdn.net/wuzhekai1985/article/details/6670298 转载:http://blog.csdn.net/gatieme/article/details/24925741