12 结构型模式-----享元模式

享元模式是一种运用共享技术解决大量细粒度对象复用问题的设计模式。通过享元工厂维护享元池,存储共享内部状态对象,外部状态则在使用时传入,减少内存消耗,适用于文档编辑器字符类等重复使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模式动机(Flyweight Pattern)顾名思义,享元模式就是运用共享技术解决大量细粒度对象的复用问题。在享元模式中,由工厂负责维护一个享元池(Flyweight Pool),用于存储具有相同内部状态的一些对象。所谓内部状态,是指一个对象的特征,我们把大多数该类对象的不变特征确定为共享特征,将其抽象为一个类放到享元池中,对于可变的部分可以通过外部状态参数传入来解决。这样的话,如果客户要使用该类型的对象,只需通过工厂从享元池中取出即可,只有在享元池中不存在的对象才会被工厂创建出来。

 

模式结构图:

 

 

模式代码:

bt_享元模式.h

#ifndef FP_H
#define FP_H
#include <iostream>
#include <map>
using namespace std;

/*
    抽象享元接口,用于接受外部状态
*/
class Flyweight
{
public:
    virtual ~Flyweight(){ }
    virtual void Operation(string extrinsicState) = 0;
};

/*
    包含共享内部状态的具体享元类
*/
class ConcreteFlyweight : public Flyweight
{
public:
    ConcreteFlyweight(){ intrinsicState = "intrinsic state"; }
    virtual void Operation(string extrinsicState)
    {
        cout << "使用共享内部状态:" << intrinsicState << endl;
        cout << "根据外部状态[ " << extrinsicState << " ]来进行工作" << endl;
    }

private:
    string intrinsicState;              // 共享的内部状态
};

/*
    非共享具体享元类,其中包含了不能共享的内部状态
*/
class UnsharedConcreteFlyweight : public Flyweight
{
public:
    UnsharedConcreteFlyweight()
    {
        intrinsicState = "intrinsic state";
        unSharedState = "unShared state";
    }
    virtual void Operation(string extrinsicState)
    {
        cout << "使用共享内部状态:" << intrinsicState << endl;
        cout << "根据外部状态[ " << extrinsicState << " ]来进行工作" << endl;
        cout << "直接使用非共享内部状态:" << unSharedState << endl;
    }

private:
    string intrinsicState;         // 共享的内部状态
    string unSharedState;          // 不能共享的内部状态
};

/*
    享元工厂类,用于创建并管理享元对象
*/
class FlyweightFactory
{
public:
    Flyweight* GetFlyweight(string key)
    {
        if(flyweights.find(key) == flyweights.end())
        {
            cout << ">>>共享池中不存在该类型的对象,正在创建中..." << endl;
            Flyweight* fw = new ConcreteFlyweight;
            flyweights.insert(make_pair(key, fw));
            return fw;
        }
        else
        {
            cout << ">>>共享池中已有该类型对象,可以立即使用" << endl;
            return flyweights[key];
        }
    }

private:
    map<string, Flyweight*> flyweights;
};

#endif // FP_H
#include "bt_享元模式.h"

int main()
{
    cout << "***** 享元模式测试 *****" << endl;

    cout << endl;
    FlyweightFactory* ff = new FlyweightFactory;
    Flyweight* fw = ff->GetFlyweight("benxin");          // 第一次创建时不存在该对象
    fw->Operation("tuzi");

    cout << endl;
    Flyweight* fw2 = ff->GetFlyweight("benxin");       // 第二次创建时直接返回该对象
    fw2->Operation("tuzi");


    cout << endl;
    cout << "<<<直接使用非共享具体享元状态>>>" << endl;    // 非共享内部状态可以直接实例化来使用
    Flyweight* fw3 = new UnsharedConcreteFlyweight;
    fw3->Operation("tuzi");

    delete fw3;
    delete fw;
    delete ff;

  return 0;
}

模式分析:

1>  享元模式中,选择频繁使用的类作为享元类,因为系统调用工厂也要产生时间上的开销,使用享元模式必须确保节约的空间开销是值得的;

2>  只有不会随着使用环境改变的状态才可以被设为共享状态;有些状态虽为内部状态,但是并不适合共享,对于这类状态,客户可以越过工厂直接实例化进行使用。

3>  享元模式的使用情况主要存在于系统中需要重复使用相同或类似的对象,如果每次都重复创建,可能会消耗大量内存空间,比如,文档编辑器中的字符类就适合作为享元类,而字符的位置参数适合作为外部状态使用,这样就可以加快文档的处理速度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值