使用场景:同一个UI图标被创建了上百次、子弹特效数字疯狂new
1.一句话理解享元模式
核心思想:相同的东西,只创建一份,多处共享。
解决:内存占用和创建成本问题
2.享元模式到底在分什么?
把对象拆成两部分:
(1)内部状态 可共享
不会变、可以复用,比如Mesh、material、Sprite
(2)外部状态 不可共享
每个实例都不一样,使用时传入,比如位置、旋转、血量、UI文本内容等
3.实战演示
(1)享元对象(共享部分)
cs
public class BulletFlyweight
{
public Mesh Mesh;
public Material Material;
public BulletFlyweight(Mesh mesh, Material material)
{
Mesh = mesh;
Material = material;
}
}
(2)享元工厂(关键)
cs
public class BulletFlyweightFactory
{
private Dictionary<string, BulletFlyweight> _cache
= new Dictionary<string, BulletFlyweight>();
public BulletFlyweight Get(string type)
{
if (!_cache.TryGetValue(type, out var flyweight))
{
flyweight = Create(type);
_cache[type] = flyweight;
}
return flyweight;
}
private BulletFlyweight Create(string type)
{
return new BulletFlyweight(
LoadMesh(type),
LoadMaterial(type)
);
}
}
(3)使用时传入外部状态
cs
public void Fire(Vector3 pos, Vector3 dir)
{
var flyweight = factory.Get("NormalBullet");
Graphics.DrawMesh(
flyweight.Mesh,
pos,
Quaternion.LookRotation(dir),
flyweight.Material,
0
);
}
4.享元模式VS对象池
| 对比 | 享元模式 | 对象池 |
|---|---|---|
| 关注点 | 共享数据 | 复用实例 |
| 是否 new | 很少 | 先 new 一批 |
| 核心 | 内存节省 | GC / 性能 |
5.享元模式常见的坑
cs
flyweight.Material.color = Color.red;
所有使用这个材质的对象都会变红
解决方案:共享对象设置只读,或者clone一份