FlyWeight 共享元对象结构模式

       Flyweight 共享元模式,描述了如何共享对象,使得可以细粒度地使用它们而无需高昂的代价。

       Flyweight 是一个共享对象,它可以同时在多个场景中使用,并且在每个场景中 flyweight 都可以作为一个独立的对象--这一点与非共享对象的实例没有区别。Flyweight 不能对它所运行的场景做出任何假设,这里的关键概念是“内部状态”和“外部状态”之间的区别。内部状态存储于 flyweight 中,它包含了独立于 flyweight 场景的信息,这些信息使得 flyweight 可以被共享。而外部状态取决于 flyweight 场景,并根据场景而变化,因此不可共享。用户对象负责在必要的时候将外部状态传递给 flyweight。

      Flyweight 模式主要适用于以下情况:

      1.一个应用程序使用了大量的对象。

      2.完全由于使用大量的对象,造成很大的存储开销。

      3.对象的大多数状态都可变为外部状态。

      4.如果删除对象的外部状态,那么可以用较少的共享对象取代很多组对象。

      5.应用程序不依赖于对象标识。由于 Flyweight 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。

     Flyweight 共享元模式的通用结构如下:

flyweight

   Flyweight 模式的参与者:

   Flyweight:描述一个接口,通过这个接口 flyweight 可以接受并作用于外部状态。

   ConcreteFlyweight:实现 Flyweight 接口,并为内部状态增加存储空间。ConcreteFlyweight 对象必须是可共享的。它所存储的状态必须是内部的:即,它必须独立于 ConcreteFlyweight 对象的场景。

   UnsharedConcreteFlyweight:并非所有的 Flyweight 子类都需要被共享。Flyweight 接口使用共享成为可能,但它并不强制共享。在 Flyweight 对象结构的某些层次,UnsharedConcreteFlyweight 对象通常将 ConcreteFlyweight 对象作为子节点。

   FlyweightFactory:创建并管理 Flyweight 对象。确保合理地共享 flyweight。当用户请求一个 Flyweight 时,FlyweightFactory 对象提供一个已创建的实例或者创建一个(不存在的话)。

   Client:维持一个对 flyweight 的引用。计算或存储一个(多个)flyweight 的外部状态。

     Flyweight 执行时所需的状态必定是内部的或外部的。内部状态存储于 ConcreteFlyweight 对象之中;而外部对象则由 Client 对象存储或计算。当用户调用 Flyweight 对象的操作时,将该状态传递给它。用户不应直接对 ConcreteFlyweight 对象存储或计算,而只能从 FlyweightFactory 对象得到 ConcreteFlyweight 对象,这可以保证对它们适当地进行共享。

     共享还意味着某种形式的引用计数和垃圾回收,这样当一个 Flyweight 不再使用时,可以回收它的存储空间。然后,当 Flyweight 的数目固定而且很小的时候,这两种操作都不必要。在这种情况下, Flyweight 完全可以永久保存。

     从上面的结构图可以看出,Flyweight  模式中有一个类似 Factory 模式的对象构造工厂 FlyweightFactory,当客户需要一个对象时候就会向 FlyweightFactory 发出请求 GetFlyweight()消息,FlyweightFactory 拥有一个管理、存储对象的“对象池”,GetFlyweight() 消息会遍历对象池中的对象,如果已存在则直接返回给 Client,否则创建一个新的对象给 Client。当然可能也有不想被共享的对象如 UnshareConcreteFlyweight。

代码示例:

   1:  #pragma once 
   2:   
   3:  #include 
  
  
   4:  #include <string>
   5:  #include 
  
  
   6:   
   7:  typedef std::string STATE;
   8:   
   9:  class Flyweight
  10:  {
  11:  public:
  12:      virtual ~Flyweight(){  }
  13:   
  14:      STATE GetIntrinsicState()
  15:      {
  16:          return m_State;
  17:      }
  18:      virtual void Operation(STATE& ExtrinsicState) = 0;
  19:   
  20:  protected:
  21:      Flyweight(const STATE& state) : m_State(state){  }
  22:   
  23:  private:
  24:      STATE m_State;
  25:  };
  26:   
  27:  //
  28:  class ConcreateFlyweight : public Flyweight
  29:  {
  30:  public:
  31:      ConcreateFlyweight(const STATE& state) : Flyweight(state){  }
  32:      virtual ~ConcreateFlyweight(){  }
  33:   
  34:      virtual void Operation(STATE& ExtrinsicState){  }
  35:  };
  36:   
  37:  // 对象工厂,客户接口
  38:  class FlyweightFactory
  39:  {
  40:  public:
  41:      FlyweightFactory(){}
  42:      ~FlyweightFactory()
  43:      {
  44:          std::list
  
  
   
   ::iterator iter1, iter2, temp;
  
  
  45:   
  46:          for (iter1 = m_listFlyweight.begin(), 
  47:              iter2 = m_listFlyweight.end(); iter1 != iter2;)
  48:          {
  49:              temp = iter1;
  50:              ++iter1;
  51:              delete *temp;
  52:          }
  53:   
  54:          m_listFlyweight.clear();
  55:      }
  56:   
  57:      Flyweight* GetFlyweight(const STATE& key)
  58:      {
  59:          std::list
  
  
   
   ::iterator iter1, iter2;
  
  
  60:   
  61:          for (iter1 = m_listFlyweight.begin(), 
  62:              iter2 = m_listFlyweight.end(); iter1 != iter2; ++iter1)
  63:          {
  64:              if ((*iter1)->GetIntrinsicState() == key)
  65:              {
  66:                  std::cout << "The Flyweight:" << key << " already exits" << std::endl;
  67:                  return (*iter1);
  68:              }
  69:          }
  70:   
  71:          std::cout << "Creating a new Flyweight:" << key << std::endl;
  72:          Flyweight* flyweight = new ConcreateFlyweight(key);
  73:          m_listFlyweight.push_back(flyweight);
  74:      }
  75:   
  76:  private:
  77:      std::list
  
  
   
       m_listFlyweight;
  
  
  78:  };

//test

   1:   
   2:  #include "FlyWeight.h"
   3:   
   4:  int main()
   5:  {
   6:      FlyweightFactory flyweightfactory;
   7:      flyweightfactory.GetFlyweight("hello");
   8:      flyweightfactory.GetFlyweight("world");
   9:      flyweightfactory.GetFlyweight("hello");
  10:   
  11:      return EXIT_SUCCESS;
  12:  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值