Blink

纸上得来终觉浅,绝知此事要躬行

设计模式:单例模式

单例模式是我接触 最早的设计模式之一,相信也是很多人也合一样,因为单例模式是设计模模式中最简单的模式之一了。我是做Unity游戏开发的,所以我就说说自己在使用Unity的过程中对单例模式的理解,如果有什么错误的地方还望各位大佬指正

单例模式介绍

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
优点:
1. 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)
2. 避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

单例模式结构图

《设计模式:单例模式》

Unity中单例模式的几种实现方式

1. 懒汉式单例模式

  • 非MonoBehaviour
public class Singleton 
{
    public static Singleton m_Instance = null;
    public static Singleton Instance
    {
        get
        {
            if(m_Instance == null)
            {
                m_Instance = new Singleton();
            }
            return m_Instance;
        }
    }
}
  • MonoBehaviour
using UnityEngine;
public class Singleton : MonoBehaviour
{
    private static Singleton m_Instance = null;
    public static Singleton Instance
    {
        get
        {
            if(m_Instance == null)
            {
                m_Instance = FindObjectOfType<Singleton>();
            }
            return m_Instance;
        }
    }
}

2.饿汉式单例

  • 非MonoBehaviour
public class Singleton 
{
    public static Singleton m_Instance = new Singleton();
    public static Singleton Instance
    {
        get
        {
            return m_Instance;
        }
    }
}
  • MonoBehaviour
using UnityEngine;
public class Singleton : MonoBehaviour
{
    public static Singleton Instance { get; private set; }
    private void Awake()
    {
        Instance = this;
    }
}

饿汉式和懒汉式的根本区别在于是否在声明时创建对象,如果是在声明的时候就创建对象就是饿汉式,在使用的是否判断对象是否为空,为空就创建的话就是懒汉式

单例模式的使用

单例模式非常简单,使用起来也很方便,不必去费尽心思的去安排对象的引用传递,所以会有很多开发者非常喜欢使用单例,造成项目中单例遍布(俗称“单例癖”)

滥用单例的弊端

  • 当我们的项目中单例遍布时,代码结构会变得非常的不清晰("单例一时爽,代码一多火葬场")
  • 容易数据混乱和内存泄漏
  • 无法进行功能扩展

在项目中我们应该避免滥用单例,其实很多时候我们会发现在代码中很多单例是没有必要使用的,如果只是为了方便调用强行使用单例的话恰恰会适得其反。设计模式的初衷是为了是我们项目更加稳定和健壮,如果使用设计模式并没有起到相应的作用,就违背了设计模式存在的意义了!为了防止滥用单例,还有一些公司是明令禁止在项目中的使用单例,但是我个人觉得这个太过于极端,单例模式只要使用的好,好处还是很大的。

单例模式就不能使用了吗?

当然不是的,每一个设计模式都有它所存在的意义,只要我们使用的合理,好处还是很多的。
下面我说一下我在Unity开发过程可以使用单例模式的地方:
– 全局服务类:如果一个类是为整个项目提供服务的,并且它是只存在一个对象实例的,例如游戏中的AudioManager,UIManager等等
– 如果一个对象我们需要它只在内存中存在一份,并且它的生命周期和和程序运行的生命周期一样

不推荐使用单例模式的地方:
– 只为单个模块服务的类:如果一个类它的仅仅是为项目中的模块服务的,我觉得合理的方式是安排引用传递,而不是使用单例,使用单例的话会增加模块的风险,例如:脏数据未及时回收,外界模块意外使用当前单例等等…

点赞

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注