Unity3D中多种单例模式的实现方式
日常瞎捣鼓,人比较懒,偶尔才写文章跟大家分享自个所学到的知识。希望对大家有帮助。
1、类中单例(基础版)
public class GameManager
{
private static GameManager instance; //单例对象,全局唯一
public static GameManager GetInstance //获取接口,也可以写成函数形式
{
get
{
if (instance == null)
instance = Activator.CreateInstance<GameManager>();
return instance;
}
}
public void Init()
{
Debug.Log("Initialized");
}
}
/// <summary>
/// 调用方式
/// </summary>
GameManager.GetInstance.Init();
优点:代码简单,实现方式简单。
缺点:项目中若需要很多类的单例来支撑的话,使用这种方式会让我们编写很多无用的重复代码(每个类都要实现一遍)
适用场景:适合单例使用较少的项目。
2、泛型单例(进阶版)
using System;
public class Singleton< T > where T : class, new()
{
private static T instance = default(T);
public static T GetInstance()
{
if (instance == null)
{
instance = new T();
}
return instance;
}
}
/// <summary>
/// 具体类的定义
/// </summary>
public class GameManager : Singleton<GameManager>
{
/// <summary>
/// 初始化游戏
/// </summary>
public void InitGame()
{
///init local data
Debug.Log("Initailized");
}
}
/// <summary>
/// 使用方式
/// </summary>
GameManager.GetInstance().InitGame();
优点:代码相对简单,只需要继承Singleton<T>类就可以实现单例类。
缺点:因为泛型约束中填写了new(),因此子类无法私有化构造函数,子类依然可以通过new来实例化对象。
适用场景:适合单例使用较多的项目。
3、“实例化”型单例(只针对U3D,针对特殊需求)
using UnityEngine;
public class SingletonWithObj<T> : MonoBehaviour where T : class //不需要再这里加new()的泛型约束
{
private static T instance = default(T);
public static T GetInstance()
{
if (instance == null)
{
GameObject go = new GameObject(typeof(T).ToString()); //第一次调用GetInstance时实例化一个U3D的空对象,并挂载单例管理脚本
DontDestroyOnLoad(go);
instance = go.AddComponent(typeof(T)) as T;
}
return instance;
}
}
/// <summary>
/// 实现方法
/// </summary>
public class ScenesManager : SingletonWithObj<ScenesManager>
{
private ScenesManager() { }
}
//当这一语句被第一次调用的时候会自动创建U3D的空对象,并自动挂载当前场景管理脚本
ScenesManager.GetInstance();
优点:在单例进阶版的基础上改进,会在U3D中创建一个空对象并把对应的管理器脚本挂上去,从而对游戏进行
相应的“特殊”管理。
缺点:必须得调用一次GetInstance才会创建对象。
使用场景:需要在游戏中生成一个空对象(挂载相应的管理脚本)用来实时管理游戏状态的情况。
不足:
1、针对第二点,子类无法声明 私有化的构造函数,导致该类依然无法禁止外部实例化。
2、针对第三点,无法让程序自动生成空对象,还得需要程序员去手动调用一次GetInstance()。
3、若有大神知道如何解决以上2点,望不吝赐教。谢谢!