码迷,mamicode.com
首页 > 其他好文 > 详细

第13章 结构型模式—享元模式

时间:2016-05-31 10:33:13      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:

1. 享元模式(Flyweight Pattern)的定义

(1)运用共享技术高效地支持大量细粒度的对象

  ①对象内部状态数据不变且重复出现,这部分不会随环境变化而改变,是可以共享的

  ②对象外部状态数据是变化的,会随环境变化而改变,是不可以共享的

  ③所谓的享元,就是把内部状态的数据分离出来共享,通过共享享元对象,可以减少对内存的占用。把外部状态分离出来,放到外部,让应用程序在使用的时候进行维护,并在需要的时候传递给享元对象使用。

  ④享元模式真正缓存和共享的是享元的内部状态,而外部状态是不被缓存共享的。同时内部状态和外部状态是独立的,外部状态的变化不会影响到内部状态。

(2)享元模式的结构和说明

 技术分享

  ①Flyweight:接口或抽象类,通过这个接口Flyweight可以接受并作用于外部状态。通过这个接口传入外部的状态,在享元对象的方法处理中可能会使用这些外部的数据。

  ②ConcreteFlyweight:具体的享元实现对象,必须是可共享的,为内部状态提供成员变量进行存储。(真正要被共享的对象

  ③UnsharedConcreteFlyweight:非共享的享元实现对象,并不是所有的Flyweight实现对象都需要共享。非共享的享元实现对象通常是对共享享元对象的组合对象,这种对象虽然不需要加入到享元工厂中去共享,但也继承自Flyweight,其好处是可以统一接口。注意,本例中的UnsharedConcreteFlyweight是从Flyweight继承而来,有时也可以不用继承自Flyweight。(该类的作用:提供外部状态存储

  ④FlyweightFactory:为控制内部状态的共享,并且让外部能简单地使用共享数据,提供一个工厂来管理享元,把它称为享元工厂。其作用主要用来创建并管理共享的享元对象享元池一般设计成键值对。这里也对外提供访问共享享元的接口。

  ⑤Client:享元客户端,主要的工作是维持一个对Flyweight的引用,计算或存储享元对象的外部状态。当然这里可以访问共享和不共享的Flyweight对象。

(3)思考享元模式

  ①享元模式的本质:分离与共享。享元模式的关键在于分离变与不变,把不变部分作为享元对象的内部状态,而变化部分则作为外部状态,由外部来维护.这样享元对象就能够被共享,从而减少对象的数量,并节省大量的内存空间。

  ②享元模式的变与不变:为什么在一个地方要预留接口,一个常见的原因是这里存在变化,可能在今后需要扩展或改变己有的实现,而预留接口作为“可插入性的保证”

  ③享元对象:又有共享(ConcreteFlyweight)与不共享(UnsharedConcreteFlyweight)之分。不共享一般出现在和组合模式合用的情况,通常共享是叶子对象,一般不共享的部分是由共享部分组合而成,由于所有细粒度的叶子对象己经缓存了,那么缓存组合对象就没有什么意义。(如权限管理中某安全实体的“查看”和“修改”是可共享的,如果将“查看”和“修改”组合成“操作”权限的话,则操作”权限是不用缓存(共享)的,因为己经在细粒度上进行了缓存)。(见后面的例子)

【编程实验】围棋软件设计

  ①内部状态:每个围棋那么多的棋子,可设置为享元对象,有如下属性颜色、大小、形状。

  ②外部状态:棋子在棋盘中的位置。这是不可共享的。

技术分享

//结构型模式:享元模式
//场景:围棋软件设计。
//内部状态——围棋棋子数量多,但分只为两类:白棋和黑棋。
//          有颜色、大小、形态等属性,是可共享的对象。
//外部状态——棋子在棋盘中的位置。

#include <iostream>
#include <string>
#include <map>

using namespace std;

//************************************享元类**************************
class Coordinate; //前向声明

//享元抽象类
class ChessFlyweight
{
public:
    virtual string& getColor() = 0;
    virtual void setColor(string color) = 0;
    
    //显示棋子在棋盘中的位置
    //可以通过这个接口,将外部状态传入享元对象中
    virtual void display(Coordinate& c) = 0;
};

//非享元对象:UnsharedConcreteFlyweight(外部状态)
class Coordinate
{
    int x,y;
public:
    Coordinate(int x, int y){this->x = x;this->y = y;}
    int getX(){return x;}
    void setX(int x){this->x = x;}

    int getY(){return y;}
    void setY(int x){this->y = y;}        
};

//享元对象:ConcreteFlyweight(内部状态)
class ConcreteChess : public ChessFlyweight
{
private:
    string color;
public:
    ConcreteChess(string color){this->color = color;} 
    string& getColor() {return color;}
    void setColor(string color){this->color = color;}
    
    void display(Coordinate& c)
    {
        cout << "Chess‘s Color: " << color << endl; 
        cout << "Position: x = " << c.getX() << " y = " << c.getY() << endl;
    }
};

//************************************享元工厂类**************************
class ChessFlyweightFactory
{
private:
    static map<string,ChessFlyweight*> chessMap;
public:
    static ChessFlyweight* getChess(string color)
    {
        ChessFlyweight* ret = chessMap[color]; 
        if(ret == NULL)
        {
            ret = new ConcreteChess(color);
            chessMap[color] = ret;
        }
        return ret;   
    }

    static void clear()
    {
        map<string, ChessFlyweight*>::iterator iter = chessMap.begin();
        while(iter != chessMap.end())
        {
            delete iter->second;
            cout <<iter->second << endl;
            ++iter;
        }
        chessMap.clear();
    }    
};

map<string,ChessFlyweight*> ChessFlyweightFactory::chessMap;

int main()
{
    ChessFlyweight* chess1 = ChessFlyweightFactory::getChess("black");
    ChessFlyweight* chess2 = ChessFlyweightFactory::getChess("black");
    ChessFlyweight* chess3 = ChessFlyweightFactory::getChess("white");
    
    cout << "chess1 = " << chess1 << endl;
    cout << "chess2 = " << chess2 << endl;
    cout << "chess3 = " << chess3 << endl;
    
    //增加外部状态的处理
    cout << "extrinsic state: " << endl;
    Coordinate c1(10, 10);
    Coordinate c2(20, 20);
    Coordinate c3(30, 30);
    
    chess1->display(c1);
    chess2->display(c2);
    chess3->display(c3);
    
    //删除享元池中的对象
    ChessFlyweightFactory::clear();
    
    return 0;
}

 

第13章 结构型模式—享元模式

标签:

原文地址:http://www.cnblogs.com/5iedu/p/5544753.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!