使用单例的目的
在我们的整个游戏生命周期中,有很多对象从始至终有且只有一个。这个唯一的实例只需要生成一次,并且直到游戏结束才需要销毁。
单例模式一般应用于管理器类,或者是一些需要持久化存在的对象。
Unity单例的懒汉模式代码:
//Unity单例的懒汉模式
private static Single _instance = null;
public static Single Instance()
{
if (_instance == null)
{
GameObject go = new GameObject("单例");
_instance = go.AddComponent<Single>();
}
return _instance;
}
Unity单例的饿汉模式代码:
//Unity单例的饿汉模式
private static Single _instance = null;
public static Single Instance()
{
return _instance;
}
void Awake()
{
if (_instance == null)
{
_instance = this;
//如果切换场景时,希望单例中的数据不清空
DontDestroyOnLoad(gameObject);//加载场景时不消毁
}
else
{
//保留老的单例,删除新的单例对象
Destroy(this.gameObject);
}
}
单例和静态的区别
1、单例方法可以继承,静态的不可以。
2、单例存在着创建实例的过程,生命周期并不是整个运行时,静态方法在编译时就存在,整个过程中是一直有效的。
如何选择单例和静态
当方法中需要用到实例本身的状态,也就是说需要用到实例成员时,使用单例调用。
当方法完全不涉及到实例,只是共享类中的一些状态的话,或者不需要任何状态,这个方法就是静态方法。
滥用单例出现的问题
1、代码的耦合性会增加。
2、单个类的职责可能会过大,违背单一指责原则。
3、因为单例的对象永远不消毁,过多的单例会造成性能问题。
主要优点
1、提供了对唯一市里的受控访问。
2、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例可以提高系统的性能。
3、允许可变数目的实例
主要缺点
1、由于单例中没有抽象层,因此单例类的扩展后很大的困难
2、单例类的职责过重,在一定程度上违背了“单一职责原则”。
3、滥用单例将带来一些负面的问题,如为了节省资源将数据库连接池对象设计为单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。