本文主要分享【享元模式和单例模式】,技术文章【【Flyweight模式】C++设计模式——享元模式】为【-Wo wo.】投稿,如果你遇到C++相关问题,本文相关知识或能到你。
1. 问题引出
假如你希望在长时间工作后放松一下, 所以开发了一款简单的游戏: 玩家们在地图上移动并相互射击。 你决定实现一个真实的粒子系统, 并将其作为游戏的特色。 大量的子弹、 导弹和爆炸弹片会在整个地图上穿行, 为玩家提供紧张刺激的游戏体验。
开发完成后, 你推送提交了最新版本的程序, 并在编译游戏后将其发送给了一个朋友进行测试。 尽管该游戏在你的电脑上完美运行, 但是你的朋友却无法长时间进行游戏: 游戏总是会在他的电脑上运行几分钟后崩溃。 在研究了几个小时的调试消息记录后, 你发现导致游戏崩溃的原因是内存容量不足。 朋友的设备性能远比不上你的电脑, 因此游戏运行在他的电脑上时很快就会出现问题。
真正的问题与粒子系统有关。 每个粒子 (一颗子弹、 一枚导弹或一块弹片) 都由包含完整数据的独立对象来表示。 当玩家在游戏中鏖战进入高潮后的某一时刻, 游戏将无法在剩余内存中载入新建粒子, 于是程序就崩溃了。
(1)模式动机
在软件系统采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价——主要指内存需求方面的代价。
如何在避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作?
(2)模式定义
运用共享技术有效地支持大量细粒度的对象。
(3)要点总结
a). 面向对象很好地解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
b). Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象状态的处理。
c). 对象的数量太大从而导致对象内存开销加大——什么样的数量才算大?这需要我们仔细的根据具体应用情况进行评估,而不能凭空臆断。
上面说的游戏例子及类图已经讲得比较清楚了,我们这里只以 “字体对象” 来简单例举代码实现,采用享元的模式,key 可以看成是字体的名称,而通过 key 可以获得该字体 font 的资源。
class Font {
private:
// unique object key
string key;
// object state
// ...
public:
Font(const string &key){
// ...
}
};
class FontFactory{
private:
map<string, Font*> fontPool;
public:
Font* GetFont(const string& key){
map<string, Font*>::iterator it = fontPool.find(key);
if (it != fontPool.end()) {
return fontPool[key];
} else {
Font* font = new Font(key);
fontPool[key] = font;
return font;
}
}
void clear(){
//...
}
}
本文《【Flyweight模式】C++设计模式——享元模式》版权归-Wo wo.所有,引用【Flyweight模式】C++设计模式——享元模式需遵循CC 4.0 BY-SA版权协议。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。