享元模式 Flyweight Pattern

享元模式 Flyweight Pattern

1.定义

享元模式,以共享的方式高效地支持大量的细粒度的对象。通过复用内存中已存在的对象,
降低系统创建对象实例的性能消耗。

2.使用场景:

  • 当系统中某个对象类型的实例较多的时候。
  • 由于使用了大量的对象,造成了很大的存储开销。
  • 对象的大多数状态都可变为外蕴状态。
  • 在系统设计中,对象实例进行分类后,发现真正有区别的分类很少的时候。

3.模式解析

图示:
这里写图片描述

  • 抽象享元类(Flyweight): 此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口或抽象类。那些需要外部状态(External State)的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。
  • 具体享元类(ConcreteFlyweight):具体享元类实现了抽象享元类所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。有时候具体享元类又称为单纯具体享元类,因为复合享元类是由单纯具体享元角色通过复合而成的。
  • 不能共享的具体享元类(UnsharableFlyweight):不能共享的享元类,又叫做复合享元类。一个复合享元对象是由多个单享元对象组成,这些组成的对象是可以共享的,但是复合享元类本身并不能共享
  • 享元工厂类(FlyweightFactoiy):享元工厂类负责创建和管理享元对象。当一个客户端对象请求一个享元对象的时候,享元工厂需要检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。
  • 客户端(Client)角色:本角色还需要自行存储所有享元对象的外部状态。

4.总结:

享元模式是通过共享有效支持大量细粒度的对象,来提供应用程序的性能,节省系统中重复创建对象实例的性能消耗

5.代码实例:

#pragma once
#include <iostream>
using namespace std;
#include <map>

class Character
{
protected:
    char symbol;
    int  width;
    int  height;
    int  ascent;
    int  descent;
    int  pointSize;
public:
    virtual void Display(int pointSize) = 0;
};

class CharacterA : public Character
{
public:
    CharacterA()
    {
        symbol = 'A';
        height = 100;
        width = 120;
        ascent = 70;
        descent = 0;
    }

    void Display(int _pointSize)
    {
        pointSize = _pointSize;
        cout<<symbol<<" (pointsize "<< pointSize <<")"<<endl;
    }
};

class CharacterB : public Character
{
public:
    CharacterB()
    {
        symbol = 'B';
        height = 100;
        width = 140;
        ascent = 72;
        descent = 0;
    }

    void Display(int _pointSize)
    {
        pointSize = _pointSize;
        cout<<symbol<<" (pointsize "<< pointSize <<")"<<endl;
    }
};

class CharacterZ : public Character
{
public:
    CharacterZ()
    {
        symbol = 'Z';
        height = 100;
        width = 100;
        ascent = 68;
        descent = 0;
    }

    void Display(int _pointSize)
    {
        pointSize = _pointSize;
        cout<<symbol<<" (pointsize "<< pointSize <<")"<<endl;
    }
};

/*
    享元工厂类
*/
class CharacterFactory
{
public:
    // 客户端通过这个函数请求享元对象
    Character* GetCharacter(char key)
    {
        Character* character = nullptr;
        map<char,Character*>::iterator it = _characters.find(key);

        if( it != _characters.end() )
        {
            character =  it->second ;
        }
        else
        { //没找到
            switch (key)
            {
            case 'A':
                character = new CharacterA();
                break;
            case 'B':
                character = new CharacterB();
                break;
            case 'Z':
                character = new CharacterZ();
                break;
            default:
                break;
            }
            _characters.insert(make_pair(key,character));
        }
        return character;
    }
private:
    map<char,Character*> _characters;
};

class FlyweightPatternExample1
{
public:

    void Start()
    {
         string document = "AAZZBBZB";
         CharacterFactory *factory = new CharacterFactory();
         int pointSize = 10;

         for( int i = 0 ; i < document.size();i++ )
         {
             pointSize++;
             Character* character =  factory->GetCharacter(document[i]);
             character->Display(pointSize);
         }
    }
};

实验结果:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值