Unity3D设计模式---单例模式详解

204 阅读2分钟

一、前言

单例模式:目的是为了让一个类在程序运行期间有且只有一个实例,方便全局访问。

用途:Unity中用作数据类、工具类、实现类,方便脚本调用。

实现流程

1.私有的构造函数,使用static静态字段

static属性在此类中是唯一的,存储在类型对象中,不是存在于实例化的对象中。
static属性不会被GC回收,随着程序的开始而创建,结束而销毁
因此,需要适当使用单例模式。

2.私有静态对象,用于实例化当前类。

3.公有的静态函数或属性,方便其它对象获取该单例类。

实现方式

1.饿汉式

   创建时机:饿汉式单例是在程序开始的时候对static属性的Instance进行初始化
   
   安全性:线程安全,static构造函数只可能运行一次
   
   存在空引用的风险,可能运行顺序关系两个类同时引用此单例,就会出现空引用错误。

2.懒汉式

    确保只创建一个单例,只需要实例时创建;
    
    变量用volatile声明,确保在访问实例变量前完成对实例变量的赋值
    
    使用locker实例上锁,而不是锁住对象本身,避免死锁
    
    避免了多个对象同时访问实例对象的时候报空引用。
    
    懒汉式延迟了实例化,直到对象第一次被访问
    
    

3.通用类

4.Mono通用类单例

    不能用new实例化,需要挂载在场景中的游戏对象上
    在脚本生命周期的Awake函数中初始化
    无需担心因Awake等调用顺序造成的空指针异常

1.饿汉式

public class Singleton
{
    //私有构造函数
    private Singleton(){}
    
    //私有对象
    private static Singleton instance;
    
    //公有对象
    pubic static Singleton Instance
    {
        get
        {
            if(null==instance)
            {
                instance=new Singleton;
            }
            return instance;
        }
    }
}

2.懒汉式

/// <summary>
/// 懒汉式单例模式通用父类
/// </summary>
public class SingletonLazy
{
    //私有构造函数
    private SingletonLazy() { }
    //私有对象
    private static volatile SingletonLazy instance;
    private static object locker = new object();
    //公有对象
    public static SingletonLazy Instance
    {
        get
        {
            if (instance == null)
            {
                lock (locker)
                {
                    if (instance == null)
                    {
                        //确保只调用一次
                        instance = new SingletonLazy();
                    }
                }
            }
            return instance;
        }
    }
}

3.通用类单例

namespace Common
{
public class Singleton<T> where T : class, new()
{
    private static T _instance;
    private static readonly object syslock = new object();

    public static T Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (syslock)
                {
                    if (_instance == null)
                    {
                        _instance = new T();
                    }
                }
            }
            return _instance;
        }
    }
}
}

4.Mono通用类单例

using UnityEngine;

namespace Common
{
    public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
    {

        private static T _instance;

        public static T Instance
        {
            get
            {
                return _instance;
            }
        }

        protected virtual void Awake()
        {
            _instance = this as T;
        }
    }
}