Unity 享元模式
初学者,自用笔记
用于把大量看起来不同但可共享的对象的内在状态(可复用部分)共享起来,把每个实例独有的外在状态(上下文)留在外部传入,从而显著降低内存占用与创建开销
常用于对象池等......
- Flyweight(享元接口/抽象享元):定义对外操作,通常要求方法接收“外在状态”作为参数(例如 Render(context) / Play(position, color))。
- ConcreteFlyweight(具体享元):真正可共享的对象,存放内在状态(例如网格、材质引用、配置数据、图标 sprite、技能静态配置等),可被多个调用方复用。
- FlyweightFactory(享元工厂):负责按 key(如 id、类型、资源路径)创建/缓存/复用 ConcreteFlyweight,保证同 key 只保留一份共享对象。
简单例子
Flyweight
// Flyweight:抽象享元(统一对外操作,要求外在状态从参数传入)
public interface IItemFlyweight
{
int Id { get; }
string Name { get; }
Sprite Icon { get; }
// 外在状态:位置、数量
void DrawAt(Vector2 screenPos, int count);
}
ConcreteFlyweight
// ConcreteFlyweight:具体享元(可共享的内在状态)
public sealed class ItemFlyweight : IItemFlyweight
{
public int Id { get; }
public string Name { get; }
public Sprite Icon { get; }
public ItemFlyweight(int id, string name, Sprite icon)
{
Id = id;
Name = name;
Icon = icon;
}
public void DrawAt(Vector2 screenPos, int count)
{
Debug.Log($"Draw {Name} x{count} at {screenPos}");
}
}
FlyweightFactory
// FlyweightFactory:享元工厂(缓存与复用)
public sealed class ItemFlyweightFactory
{
private readonly Dictionary<int, IItemFlyweight> _cache = new();
public IItemFlyweight Get(int itemId)
{
if (_cache.TryGetValue(itemId, out var fw))
return fw;
var name = $"Item_{itemId}";
var icon = Resources.Load<Sprite>($"Icons/{itemId}");
fw = new ItemFlyweight(itemId, name, icon);
_cache[itemId] = fw;
return fw;
}
}