23种设计模式(10)--Flyweight模式

本文深入介绍了享元模式的概念及其在字符处理中的应用。探讨了抽象享元、具体享元、复合享元及享元工厂的角色,并通过代码示例展示了如何通过共享技术有效支持大量细粒度对象。

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

Flyweight模式结构:


享元模式(Flyweight):运用共享的技术有效地支持大量细粒度的对象。

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

内部状态与外部状态:在享元对象内部并且不会随着环境改变而改变的共享部分,可以称之为享元对象的内部状态,反之随着环境改变而改变的,不可共享的状态称之为外部状态。

代码实现:关于字符处理

document.h

#ifndef _DOCUMENT_H_
#define _DOCUMENT_H_

#include <string>
#include <vector>

using namespace std;

// The 'Flyweight' abstract class
class character
{
public:
    //析构函数
    virtual ~character();
    //应用外部状态
    virtual void Display(int width,int height,int ascent,int descent,int pointSize)=0;
    //获取内部状态
    virtual char GetSymbol()=0;
protected:
    /*-----内部状态---------*/
    char symbol;
    /*----------------------/

    /*-----外部状态---------*/
    int width;
    int height;
    int ascent;
    int descent;
    int pointSize;
    /*----------------------*/
    //构造函数
    character(char c);
};

//A 'ConcreteFlyweight' class
class characterA:public character
{
public:
    characterA(char c);
    ~characterA();
    virtual void Display(int width,int height,int ascent,int descent,int pointSize);
    virtual char GetSymbol();
protected:
private:
};

//B 'ConcreteFlyweight' class
class characterB:public character
{
public:
    characterB(char c);
    ~characterB();
    virtual void Display(int width,int height,int ascent,int descent,int pointSize);
protected:
private:
};

//C 'ConcreteFlyweight' class
class characterC:public character
{
public:
    characterC(char c);
    ~characterC();
    virtual void Display(int width,int height,int ascent,int descent,int pointSize);
protected:
private:
};

//D 'ConcreteFlyweight' class
class characterD:public character
{
public:
    characterD(char c);
    ~characterD();
    virtual void Display(int width,int height,int ascent,int descent,int pointSize);
protected:
private:
};
/*
...
*/

//The 'FlyweightFactory' class
class characterFactory
{
public:
    characterFactory();
    ~characterFactory();
    //申请一个character对象
    character* GetCharacter(char);
    //获取存储的character*数量
    vector<character*>::size_type GetCount();
private:
    //保存character*的容器,可以换成List等其它容器
    vector<character*> m_vecCharacter;
};

#endif
#include "Document.h"
#include <iostream>

character::character(char c)
{
    this->symbol = c;
}

character::~character()
{
}

characterA::characterA(char c):character(c)
{
}

characterA::~characterA()
{
}

char characterA::GetSymbol()
{
    return this->symbol;
}

void characterA::Display(int width,int height,int ascent,int descent,int pointSize)
{
    //接收并作用外部状态
    this->ascent = ascent;
    this->descent = descent;
    this->height = height;
    this->pointSize = pointSize;
    this->width = width;

    cout << this->symbol <<" "
     << this->ascent <<" "
     << this->descent <<" "
     << this->height <<" "
     << this->pointSize <<" "
     << this->width << endl;
}

characterFactory::characterFactory()
{}

characterFactory::~characterFactory()
{}

character* characterFactory::GetCharacter(char c)
{
    vector<character*>::iterator iter = this->m_vecCharacter.begin();
    for(;iter != this->m_vecCharacter.end();iter++)
    {
        if((*iter)->GetSymbol() == c)
        {
            return *iter;
        }
    }
    character* pf = new characterA(c);
    this->m_vecCharacter.push_back(pf);
    return pf;
}

vector<character*>::size_type characterFactory::GetCount()
{
    return this->m_vecCharacter.size();
}
client

//#include "Flyweight.h"
#include "Document.h"
#include <iostream>
#include <string>

using namespace std;

int main()
{
    //存储外部状态
    int ascent = 70;
    int descent = 0;
    int height = 100;
    int width = 120;
    int pointSize = 10;

    string test = "AABCDDEFGHI";
    string::iterator it = test.begin();
    characterFactory* pcF = new characterFactory();
    for(;it!=test.end();it++)
    {
        pointSize++;
        char c = *it;
        //申请一个character对象
        character* charc= pcF->GetCharacter(c);
        //应用外部状态
        charc->Display(width,height,ascent,descent,pointSize);
    }
    vector<character*>::size_type sizeChar = pcF->GetCount();
    cout << "count:" << sizeChar << endl;

    return 0;
}

每个Flyweight都有相应的外部状态和内部状态,不过外部状态需要传递参数通过函数调用来表现,所以外部状态需要另外的存储位置。

代码转自:http://www.cnblogs.com/jiese/p/3171463.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值