设计模式(11) 享元模式(FLYWEIGHT)(二)

2014-11-24 02:50:19 · 作者: · 浏览: 4
以将该属性外部存储于GlyphContext对象中 实现:GlyphContext是一个外部状态的存储库,它维持Glyph与字体之间的一种简单映射关系。 使用:对于任何操作,如果它需要知道在给定场景下Glyph字体,都会有一个GlyphContext实例作为参数传递给它。然后该操作就可以查询GlyphContext以获取该场景中的字体信息了。 注意:当使用Glyph时,Glyph子类的迭代和管理操作必须更新GlyphContext。
class Glyph {
public:
    GlyphContext();
    virtual ~GlyphContext();
    
    virtual void Next(int step = 1);
    virtual void Insert(int quantity = 1);
    virtual Font* GetFont();
    virtual void SetFont(Font*, int span = 1);
private:
    int _index;
    BTree* _fonts;
};
Btree: 存储Glyph到字体的映射。树中的每个节点都标有字符串的长度,而向这个字符串传递字体信息。树中的叶节点指向一种字体,而内部的字符串分成了很多子字符串,每一个对应一种叶节点。 文本信息如下: \\ Btree结构可能如下图所示: \\ 假设遍历到索引102。 目标1:将“except”的字体设置为“Time 12”字体。 代码如下:
GlyphContext gc;
Font* time12 = new Font("Times-Roman-12");
Font* timeItalic12 = new Font("Times-Italic-12");
// ...
gc.SetFont(times12, 6);
新的Btree结构如下所示(黑体表示变动): \\ 目标2:在单词“expect”前用12-point Times Itali y"http://www.2cto.com/kf/yidong/wp/" target="_blank" class="keylink">WPX1szlzO2809K7uPa1pbTKRG9u"t(包含一个紧跟着的空格)。假定gc仍在索引位置102 代码:
gc.Insert(6);
gc.SetFont(timesItalic12, 6);
变动后的Btree结构: \\ 使用Btree结构的优点:
  • 查询当前Glyph字体时,向下搜索Btree,同时增加索引,直至找到当前索引的字体为止
  • 由于字体变化频率相对较低,所以这棵树相对于Glyph结构较小
  • 存储耗费低,同时也不会过多的增加查询时间 FlyweightFactory类:负责创建Glyph类,并确保它们进行合理共享,即Glyph类的管理类。 职责:实例化Character和其他类型的Glyph。
    const int NCHARCODES = 128;
    
    class GlyphFactory {
    public:
        GlyphFactory();
        virtual ~GlyphFactory();
        virtual Character* CreateCharacter(char);
        virtual Row* CreateRow();
        virtual Column* CreateColumn();
        // ...
    private:
        Character* _character[NCHARCODES];
    };
    
    // _character数组包含一些指针,指向以字母代码为索引的Character Glyphs。该数组在构造函数中被初始化为零。
    GlyphFactory::GlyphFactory () {
        for (int i = 0; i < NCHARCODES; ++i) {
            _character[i] = 0;    
        }
    };
    
    //对某个字符的查找,如果存在,返回相应的Glyph,如果不存在,创建相应的Glyph,将其放入数组中
    Character* GlyphFactory::CreateCharacter (char c) {
        if (!_character[c]) {
            _character[c] = new Character(c);
        }
        return _character[c];
    }
    
    // 其他操作仅需要在每次被调用时实例化一个新对象,因为非字符的Glyph不能被共享
    Row* GlyphFactory::CreateRow () {
        return new Row;
    }
    
    Column* GlyphFactory::CreateColumn () {
        return new Column;
    }


    相关模式:
    • Flyweight模式通常和组合模式结合起来,用共享叶节点的有向无环图实现一个逻辑上的层次结构
    • 通常,最好用Flyweight实现State和Strategy对象
      参考资料: 《设计模式:可复用面向对象软件的基础》