十一、Flyweight(享元)
情景举例:
运用共享技术有效地支持大量细粒度的对象。
代码示例:
/* Flyweight抽象类。其操作中的GlyphContext下文会介绍 */ class Glyph { public: virtual ~Glyph(); virtual void Draw(Window*, GlyphContext&); /* */ virtual void SetFont(Font*, GlyphContext&); virtual Font* GetFont(GlyphContext&); /* */ virtual void First(GlyphContext&); virtual void Next(GlyphContext&); virtual bool IsDone(GlyphContext&); virtual Glyph* Current(GlyphContext&); /* */ virtual void Insert(Glyph*, GlyphContext&); virtual void Remove(GlyphContext&); protected: Glyph(); }; /* Flyweight具体类。 */ class Character : public Glyph { public: Character(char); virtual void Draw(Window*, GlyphContext&); private: char _charcode; }; /* GlyphContext是一个外部状态的存储库。它维持着实际字体与Glygh类的映 * 射关系。在给定场景下,都会有一个GlyphContext对象作为Glygh类的参数。 */ class GlyphContext { 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; }; /* 主程序中只给出了创造给定场景下某个GlyphContext对象的方法。 */ void dummy () { /* */ GlyphContext gc; Font* times12 = new Font("Times-Roman-12"); Font* timesItalic12 = new Font("Times-Italic-12"); // ... gc.SetFont(times12, 6); /* */ gc.Insert(6); gc.SetFont(timesItalic12, 6); /* */ } /* 抽象工厂。负责创建Glygh并确保对它们进行合理共享。 */ const int NCHARCODES = 128; class GlyphFactory { public: GlyphFactory(); virtual ~GlyphFactory(); /* */ virtual Character* CreateCharacter(char); virtual Row* CreateRow(); virtual Column* CreateColumn(); // ... private: Character* _character[NCHARCODES]; }; /* 构造函数中对共享池全部清0 */ GlyphFactory::GlyphFactory () { for (int i = 0; i < NCHARCODES; ++i) { _character[i] = 0; } } /* 如果在共享池中找不到则创建一个新的对象并放入共享池,反之则直接取出。 */ Character* GlyphFactory::CreateCharacter (char c) { if (!_character[c]) { _character[c] = new Character(c); } return _character[c]; } /* 行与列无法共享。普通的抽象工厂模式 */ Row* GlyphFactory::CreateRow () { return new Row; } /* */ Column* GlyphFactory::CreateColumn () { return new Column; }
个人理解:
个人觉得对享元模式的理解尚浅。该模式体现共享思想的类是一个抽象工厂类,该类的实现确保了细粒度对象的合理共享。在例子中的GlyphContext类个人认为可能与模式本身无关,只是由Glygh类操作的参数类,在这里只是外部存储了给定场景下的字体状态。