zoukankan      html  css  js  c++  java
  • 设计模式C++描述----12.享元(Flyweight)模式

    一. 概述

    在面向对象系统的设计何实现中,创建对象是最为常见的操作。

    这里面就有一个问题:如果一个应用程序使用了太多的对象,就会造成很大的存储开销。特别是对于大量轻量级(细粒度)的对象,比如在文档编辑器的设计过程中,我们如果没有为字母创建一个对象的话,系统可能会因为大量的对象而造成存储开销的浪费。

    例如一个字母“a”在文档中出现了100000次,而实际上我们可以让这一万个字母“a”共享一个对象,当然因为在不同的位置可能字母“a”有不同的显示效果(例如字体和大小等设置不同),在这种情况我们可以为将对象的状态分为“外部状态”和“内部状态”,将可以被共享(不会变化)的状态作为内部状态存储在对象中,而外部对象(例如上面提到的字体、大小等)我们可以在适当的时候将外部对象最为参数传递给对象(例如在显示的时候,将字体、大小等信息传递给对象)。

    二. 享元模式

    定义:运用共享技术有效地支持大量细粒度的对象

    结构图如下:

    Flyweight:所有具体享元类的父类,或接口

    ConcreteFlyweight:具体享元类,实现具体的操作

    UnshareConcreteFlyweight:不需要共享的子类

    FlyweightFactory:合理的创建并管理享元类

    代码如下:

    1. //享元类  
    2. class Flyweight  
    3. {  
    4. public:  
    5.     virtual ~Flyweight() {}  
    6.   
    7.     virtual void Operation(const string& extrinsicState) {}  
    8.       
    9.     string GetIntrinsicState()  
    10.     {  
    11.         return this->_intrinsicState;  
    12.     }  
    13.   
    14. protected:  
    15.     Flyweight(string intrinsicState)  
    16.     {  
    17.         this->_intrinsicState = intrinsicState;  
    18.     }  
    19.   
    20. private:  
    21.     string _intrinsicState;  
    22. };  
    23.   
    24. //具体享元类  
    25. class ConcreteFlyweight:public Flyweight  
    26. {  
    27. public:  
    28.     ConcreteFlyweight(string intrinsicState):Flyweight(intrinsicState)  
    29.     {  
    30.         cout<<"ConcreteFlyweight Build....."<<intrinsicState<<endl;  
    31.     }  
    32.   
    33.     ~ConcreteFlyweight() {}  
    34.   
    35.     //实现接口  
    36.     void Operation(const string& extrinsicState)  
    37.     {  
    38.         cout<<"内部["<<this->GetIntrinsicState()<<"] 外部["<<extrinsicState<<"]"<<endl;  
    39.     }  
    40. };  
    41.   
    42. //享元工厂  
    43. class FlyweightFactory  
    44. {  
    45. public:  
    46.     FlyweightFactory() {}  
    47.   
    48.     ~FlyweightFactory() {}  
    49.   
    50.     //确保合理的共享 Flyweight  
    51.     Flyweight* GetFlyweight(const string& key)  
    52.     {  
    53.         vector<Flyweight*>::iterator it = _fly.begin();  
    54.   
    55.         for (; it != _fly.end();it++)  
    56.         {  
    57.             if ((*it)->GetIntrinsicState() == key)  
    58.             {  
    59.                 cout<<"already created by users...."<<endl;  
    60.                 return *it;  
    61.             }  
    62.         }  
    63.   
    64.         Flyweight* fn = new ConcreteFlyweight(key);  
    65.         _fly.push_back(fn);  
    66.         return fn;  
    67.     }  
    68.   
    69. private:  
    70.     vector<Flyweight*> _fly;  
    71. };  
    72.   
    73.   
    74. //测试  
    75. int main(int argc,char* argv[])  
    76. {  
    77.     FlyweightFactory* fc = new FlyweightFactory();  
    78.       
    79.     //不同的对象,享元工厂将会创建新的享元类  
    80.     Flyweight* fw1 = fc->GetFlyweight("Object A");  
    81.     Flyweight* fw2 = fc->GetFlyweight("Object B");  
    82.       
    83.     //相同的对象,享元工厂将会使用一个已创建的享元类  
    84.     Flyweight* fw3 = fc->GetFlyweight("Object A");  
    85.   
    86.     return 0;  
    87. }  

    三. 说明

    1. 享元工厂类是重点,因为它创建并管理享元对象,对没有的对象它会创建,对已有的对象它会提供一个已创建的实例

    2. 可以想像有一个对象池,里面都是一些享元类,享元工厂的作用就是从对象池里取对象。

    3. 它的目的是大幅度地减少需要实例化的类的数量

  • 相关阅读:
    nodepad++中的正则表达式匹配和替换操作。
    QT Creator配置环境和安装
    圣诞树小程序的制作
    C#编辑xml文件
    delegate里的Invoke和BeginInvoke
    记录RFID操作错误
    关于Panel隐藏横向滚动条
    随笔
    Java图形打印 上下对称三角星
    Centos 7.5安装 Redis 5.0.0
  • 原文地址:https://www.cnblogs.com/any91/p/3248000.html
Copyright © 2011-2022 走看看