【设计模式】结构型模式:享元模式

意图

享元模式是一种结构型设计模式,它摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,让你能在有限的内存容量中载入更多对象。

问题

你需要开发一款游戏,玩家们在地图上移动并相互射击。你决定实现一个真实的粒子系统,并将其作为游戏的特色。大量的子弹、导弹和爆炸弹片会在整个地图上穿行,为玩家提供紧张刺激的游戏体验。
但是由于每个粒子(一颗子弹、 一枚导弹或一块弹片)都由包含完整数据的独立对象来表示。当玩家在游戏中鏖战进入高潮后的某一时刻,游戏将无法在剩余内存中载入新建粒子,于是游戏就崩溃了。


问题:内存不足

解决方案

观察粒子Particle类,你可能会注意到颜色 color和粒子图 sprite这两个成员变量所消耗的内存要比其他变量多得多。对于所有的粒子来说,这两个成员变量所存储的数据几乎完全一样(比如所有子弹的颜色和粒子图都一样)。

享元模式

每个粒子的另一些状态(坐标、 移动矢量和速度)则是不同的。因为这些成员变量的数值会不断变化。 这些数据代表粒子在存续期间不断变化的情景,但每个粒子的颜色和粒子图则会保持不变。

对象的常量数据通常被称为内在状态,其位于对象中,其他对象只能读取但不能修改其数值。而对象的其他状态常常能被其他对象 “从外部” 改变,因此被称为外在状态。

享元模式建议不在对象中存储外在状态,而是将其传递给依赖于它的一个特殊方法。程序只在对象中保存内在状态,以方便在不同情景下重用。这些对象的区别仅在于其内在状态(与外在状态相比,内在状态的变体要少很多),因此你所需的对象数量会大大削减。

让我们回到游戏中。假如能从粒子类中抽出外在状态,那么我们只需三个不同的对象(子弹、导弹和弹片)就能表示游戏中的所有粒子。

享元模式结构

享元模式结构

小结

适合应用场景

  • 仅在程序必须支持大量对象且没有足够的内存容量时使用享元模式。

应用该模式所获的收益大小取决于使用它的方式和情景。它在下列情况中最有效:

  1. 程序需要生成数量巨大的相似对象。
  2. 这将耗尽目标设备的所有内存。
  3. 对象中包含可抽取且能在多个对象间共享的重复状态。

优点

  • 如果程序中有很多相似对象,那么你将可以节省大量内存。

缺点

  • 你可能需要牺牲执行速度来换取内存,因为他人每次调用享元方法时都需要重新计算部分情景数据。

  • 代码会变得更加复杂。

参考

22种设计模式:refactoringguru.cn/design-patterns
《设计模式:可复用面向对象软件的基础》

你可能感兴趣的:(【设计模式】结构型模式:享元模式)