🪶
一句话理解:享元模式让大量对象共享不可变的公共数据,只在每个实例中保留独有状态,以减少内存和重复初始化。

内部状态与外部状态

  • 内部状态:可安全共享且通常不可变,如名称、图标、基础属性和音效引用。
  • 外部状态:属于单个实例,如当前位置、当前生命值和目标。
只有正确拆分两类状态,共享才不会造成实例之间互相污染。

Unity 示例:共享敌人定义

数百个敌人可以引用同一个 EnemyDefinition。配置与资源引用只存一份,而 currentHealth 保留在各自实例中。

Flyweight Factory

纯 C# 场景中常用字典按 key 缓存和返回享元对象。Unity 项目里的 Asset Database 和序列化引用已经能承担很多共享职责,不必总是再写一层工厂。

适用场景

  • 大量同类单位、植被、弹道配置
  • 字形、粒子参数、动画配置
  • 地图瓦片和重复 UI 样式
先用 Profiler 证明重复数据确实是瓶颈,再引入共享结构。

相关优化

享元减少的是数据重复,不会自动减少 GameObject、Transform 或渲染开销。大量对象还可能需要对象池、GPU Instancing、ECS 或批处理。不要把这些技术混为一谈。

风险

共享对象应视为只读。运行时直接修改共享 ScriptableObject 会影响所有引用者,甚至在编辑器中污染资产。可变数据必须留在实例,或先复制运行时配置。

小结

享元模式的关键不是“缓存所有对象”,而是找出可共享的稳定数据,并为实例状态划清边界。