Unity泛型工厂模式优化咨询:避免重复类型参数
Unity工厂类实现优化建议
问题场景
我正尝试在Unity中实现一个基工厂类,它包含一组带不同ID的预制体实例列表,需要为游戏实现多个不同的工厂,每个工厂对应各自的预制体列表。
已定义通用接口ICreatable,传入ID时工厂会找到对应预制体并返回实例化对象,但当前实现存在冗余问题:创建子类工厂时需要重复传入相同的类型参数(比如AmmoFactory : BaseFactory<BaseAmmo, BaseAmmo>),希望得到优化方案。
现有代码
ICreatable接口
public interface ICreatable<T> where T : MonoBehaviour { #region Properties public int Id { get; } public T Item { get; } #endregion Properties }
BaseFactory基类
public class BaseFactory<T, U> where T : MonoBehaviour where U : ICreatable<T> { #region Variables protected T cachedItem; protected U cachedCreatable; protected List<U> creatableList; #endregion Variables #region Functions public BaseFactory(List<U> creatableList) { this.creatableList = new List<U>(creatableList); } ~BaseFactory() { creatableList = null; } public T Manufacture(int id) { cachedCreatable = GetCreatable(id); cachedItem = UnityEngine.Object.Instantiate(cachedCreatable.Item, null); return cachedItem; } private U GetCreatable(int id) { for (int i = 0; i < creatableList.Count; i++) { cachedCreatable = creatableList[i]; if (cachedCreatable != null && cachedCreatable.Id == id) { return cachedCreatable; } } return default; } #endregion Functions }
现有子类工厂写法
public class AmmoFactory : BaseFactory<BaseAmmo, BaseAmmo> { }
优化方案
1. 简化泛型约束,消除重复类型参数
重新设计接口,让实现类自身继承MonoBehaviour并实现ICreatable,这样工厂类只需单个泛型参数:
调整后的ICreatable接口
public interface ICreatable { int Id { get; } GameObject Prefab { get; } // 直接返回预制体,或保持泛型约束 } // 或者保持泛型但让T同时继承MonoBehaviour和ICreatable<T> public interface ICreatable<T> where T : MonoBehaviour, ICreatable<T> { int Id { get; } T Item { get; } }
优化后的BaseFactory类
以无泛型接口为例,工厂类简化为单泛型参数,同时用字典提升查找效率:
public class BaseFactory<T> where T : MonoBehaviour, ICreatable { private readonly Dictionary<int, T> _creatableMap; public BaseFactory(List<T> creatableList) { // 初始化时转字典,将查找复杂度从O(n)降到O(1) _creatableMap = creatableList.Where(item => item != null) .ToDictionary(item => item.Id, item => item); } public T Manufacture(int id) { if (_creatableMap.TryGetValue(id, out var creatable)) { return UnityEngine.Object.Instantiate(creatable.Item, null); } Debug.LogError($"未找到ID为{id}的可创建对象"); return null; } }
优化后的子类工厂写法
public class AmmoFactory : BaseFactory<BaseAmmo> { }
2. 移除不必要的缓存字段
原工厂类中的cachedItem和cachedCreatable属于实例级临时变量,每次Manufacture都会被覆盖,没有缓存价值,建议直接移除,避免内存占用和潜在空引用问题。
3. 删除冗余析构函数
Unity中MonoBehaviour对象的生命周期由引擎管理,手动在析构函数中设置creatableList = null无意义,还可能增加GC开销,直接删除即可。
内容的提问来源于stack exchange,提问作者Roduraz
相关产品推荐
相关产品推荐

