单例模式是我们最常用的一种设计模式。
主要优点:
1、提供了对唯一实例的受控访问。
2、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
3、允许可变数目的实例。
主要缺点:
1、由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。
2、单例类的职责过重,在一定程度上违背了“单一职责原则”。
3、滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。
首先是普通的C#单例模式
public abstract class CSharpSingletion<T> where T : new() {
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
instance = new T();
}
return instance;
}
}
}
using UnityEngine;
using System.Collections;
public class AudioSingletion : CSharpSingletion<AudioSingletion> {
public int i = 1;
}
这里使用了范型类约束,当我们需要使用单例类时继承这个单例类就可以,这样就可以提高代码的复用性。
接下来是Unity中继承MonoBehaviour的单例类型,这里做法和第一种类似,同样使用继承单例类的方法来实现统一管理。
using UnityEngine;
using System.Collections;
public class MonoSingletion<T> : MonoBehaviour where T :MonoBehaviour{
private static string MonoSingletionName = "MonoSingletionRoot";
private static GameObject MonoSingletionRoot;
private static T instance;
public static T Instance
{
get
{
if (MonoSingletionRoot==null)//如果是第一次调用单例类型就查找所有单例类的总结点
{
MonoSingletionRoot = GameObject.Find(MonoSingletionName);
if (MonoSingletionRoot==null)//如果没有找到则创建一个所有继承MonoBehaviour单例类的节点
{
MonoSingletionRoot = new GameObject();
MonoSingletionRoot.name = MonoSingletionName;
DontDestroyOnLoad(MonoSingletionRoot);//防止被销毁
}
}
if (instance == null)//为空表示第一次获取当前单例类
{
instance = MonoSingletionRoot.GetComponent<T>();
if (instance == null)//如果当前要调用的单例类不存在则添加一个
{
instance = MonoSingletionRoot.AddComponent<T>();
}
}
return instance;
}
}
}
using UnityEngine;
using System.Collections;
public class MusicSingletion : MonoSingletion<MusicSingletion> {
public void Show()
{
Debug.Log("Play Music");
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}使用时只需要在其他地方调用 MusicSingletion.Instance.Show();就可以