文章目录

  • 创建型模式--单例模式
  • 一、单例模式是什么?
  • 二、UML图
  • 三、实现方式
  • 1.普通实现
  • 2.泛型实现(属性访问)
  • 3.多线程单例
  • 四、优缺点
  • 1.优点
  • 2.缺点
  • 五、适用场景
  • 六、如何正确使用单例?



一、单例模式是什么?

定义:保证一个类只有一个实例,并且提供了访问了该实例的全局访问点

通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象,一个最好的办法就是:让类自身保存它的唯一实例,这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法


二、UML图

//TODO


三、实现方式

1.普通实现

using UnityEngine;
public class Singleton : MonoBehaviour
{
	//直接访问
    public static  Singleton instance;
    //私有化构造方法,堵死外界利用new 创建单例实类的可能性
    private Singleton()
    {
    }

    private void Awake()
    {        
        if(instance == null)
        {
            Instance = this;
        }
       else
       {
            if(instance = null)
            {
                Destory(gameobject);
            }
       }
       DontDestoryOnLoad(gameobject);
    }
}

2.泛型实现(属性访问)

using UnityEngine;
public class Singleton<T> where T : new()
{
    private static T _instance;
    private static readonly object objlock = new object();
 
    public static T Instance
    {
        get
        {
            if (_instance == null)
            {
            	//线程锁
                lock (objlock)
                {
                    if (_instance == null)
                    {
                        _instance = new T();
                    }
                }
            }
            return _instance;
        }
    }
}

3.多线程单例

//TODO


四、优缺点

1.优点

  1. 单例模式提供了对唯一实例的受控访问。
  2. 它在运行时实例化。
  3. 如果没人用,就不必创建实例。由于单例只在第一次被请求时实例化,如果游戏永远不请求,那么它不会被实例化

2.缺点

因为单例是一个全局变量

  1. 理解代码更加困难,函数代码更加难理解
  2. 促进了耦合的发生。单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。
  3. 对并行不友好。
  4. 由于垃圾回收机制,可能会导致单例数据丢失

五、适用场景

  1. 系统只需要一个实例对象进行管理或者特定功能,如log管理器
  2. 单个实例只允许使用一个公共访问点,如怪物管理器

六、如何正确使用单例?

糟糕设计的单例通常会“帮助”另一个类增加代码。 如果可以,把所有的行为都移到单例帮助的类中。
便利的访问是我们使用单例的一个主要原因。 这让我们在不同地方获取需要的对象更加容易。 这种便利是需要付出代价的——在我们不想要对象的地方,也能轻易地使用。

给实例提供方便的访问方法

  1. 把你需要的对象简单地作为参数传给需要它的函数。
  2. 从基类中获得,使用子类沙箱。
  3. 让现有的全局对象捎带需要的东西,来减少全局变量类的数目,避免产生大量实例。

参考:
1.大话设计模式
2.游戏设计模式