• 【结构型】Flyweight模式


        享元模式的主要目的、意图是为对象的大量使用提供一种共享机制。该模式的思想重在复用、共享复用。像文字、列表中的格子等这类多数都是需要考虑复用技术,否则必将大量耗费内存空间而使资源以及性能等大量耗费。该模式的类关系图参考如下:

        模式的编码结构参考如下:

     1 namespace flyweight
     2 {
     3     class Flyweight {};
     4     class ConcreteFlyweight : public Flyweight {};
     5     class UnsharedFlyweight : public Flyweight {};
     6     class FlyweightFactory
     7     {
     8     public:
     9         typedef int TKey;
    10         Flyweight* getFlyweight(const TKey& key) {
    11             auto pRetItem = this->getItemByKey(key);
    12             if (nullptr == pRetItem) {
    13                 pRetItem = this->createNewInstance(key);
    14                 if (nullptr != pRetItem) {
    15                     this->addNewItem(pRetItem);
    16                 }
    17             }
    18             return pRetItem;
    19         }
    20 
    21     private:
    22         Flyweight* getItemByKey(const TKey& key) {
    23             // some code here........
    24             return nullptr;
    25         }
    26 
    27         Flyweight* createNewInstance(const TKey& key) {
    28             // some code here........
    29             return nullptr;
    30         }
    31 
    32         void addNewItem(Flyweight* pNewItem) {
    33             // some code here........
    34         }
    35 
    36     };//class FlyweightFactory
    37 
    38 }//namespace flyweight
    Flyweight编码结构参考

        关于复用、共享技术,多数情况下我们也会使用Cache,或者使用空闲队列等用以暂时存放当前不正在被使用的那些“垃圾”对象。待下次有需要时,再从中取出来使用。如:列表UI的格子,当格子移出可视框区域后,我们不会立即将它们删除掉,而是移入空闲队列,另一端因为空出一片“空地”,于是需要一个或几个新的格子来填补该区域,此时就从空闲队列中取出可用的,如果取不到,此时才去新创建出格子实例。还有像游戏AI中的许多对象也是如此。

        再如像文字引擎或图形渲染库等,一个文字或一张图像的纹理在引擎中可能就只有一份轮廓、图像实例,而在渲染时,由外部指定相关参数,如:位置,混合颜色、系数、缩放比例等,将这份实例对象,渲染展现到各个位置上,从而实现资源的共享使用。如不这样,则内存资源的使用将耗费极大(因为图像是相当耗资源的)。

        在前面【结构型】AbstractFactory模式 & FactoryMethod模式中,也曾提到过,我们可以通过一些技术手段,实现通用的带Cache的通用工厂,从而达到资源的复有目的。

        Cache技术与享元模式的探讨:

        1) Cache注重的是复用,重复利用。说白了,被复用的对象,在被重新使用时,也仅供1个使用者使用,并未达到共享、共用的目的。

        2) 享元更注重共享使用,即:对某对象共享使用,一个对象,可以供N个使用者使用。或许形象点比喻,可理解为:一个对象实例,然后有着一个使用它的引用计数器一样对其进行使用计数。有N个对象使用它时,它的记数就是n。当都没有被时,这时,它才有可能被从内存中移除。此时这边就有个疑问:既然N个使用者在使用同一个对象,那这对象的数据不乱套了么?是的,也正是因为此,在使用享元模式设计对象时,必需要对Flyweight对象的数据属性进行区别,将公共的数据由模式内部维护,而特性数据,只能由使用者自己维护、提供。因此,这N个使用者,在使用共享对象时,所进行的操作,都只会影响他们自己持有的特性数据属性。这点很关键,也是难点。

        3) 享元模式在设计上,也并非说所提供的对象一定都必需是要共享的,它也可以提供不共享的对象。极端情况下,所提供的对象,全都是不共享的,然后再支持对象回收机制,此时,其实就退化成前面说的Cache了。

  • 相关阅读:
    POST和GET的区别
    Java设计模式6大原则
    JAVA23种工厂模式
    使用jsp实现用户登录请求
    MVC模式
    使用idea查询数据库内容
    mysql常见错误
    定义外键和建表原则
    CSS制作圆角边框
    2、JS的编写位置
  • 原文地址:https://www.cnblogs.com/tongy0/p/5534077.html
Copyright © 2020-2023  润新知