【设计模式】单例模式(Unity3D/C#)

本文详细介绍了单例模式的概念,包括C#中的饿汉模式和懒汉模式,以及Unity中的伪单例模式。在C#中,通过静态方法和构造函数的访问级别控制单例的创建。而在Unity中,由于MonoBehavior的特性,单例成为伪单例,通过FindObjectOfType方法获取。文章还探讨了为何在Unity中不能直接应用C#的复用模式创建单例,以及使用单例模式的原因,如游戏任务管理等场景。
摘要由CSDN通过智能技术生成

【题外话】

  最近整理博客,虽然文章不多,但是文章命名和文章分类好像也整的很混乱- -。之后会本着标题命名便于检索、文章分类依据文章所涉及知识概念的原则进行划分。

【单例概述】

定义:单例,顾名思义,单个实例,即应用单例模式的类有且只有一个实例对象,并提供一个全局访问点来共其他类与对象访问。

(1)有且只有一个实例对象。
  有实例对象说明该类不是抽象类;只有一个实例对象表示不能随时随地的new一个该类的对象出来(这不是对开发者的约定,而是代码层面上的约定,即如果你这样做了,编辑器会提示你错误),即该类的构造函数是private级别,只能在类的内部构建实例对象;
(2)提供全局访问点使其他类与对象访问。
  这说明应用单例模式的类在提供实例访问方法时,该方法应该是静态的。

  有了如上的分析,就可以很轻松的创建单例类了,代码并不是很复杂。为什么要分成“C#中的单例模式”和“Unity中的伪单例模式”,前者指C#语言本身,后者指在Unity的Mono框架下。还有一点要说的,下面所有所有的例子都只是说明单例如何创建,不是说类中就这么点东西。。。- -

【C#中的单例模式】

  在单例模式中,根据应用情况的不同,也有着不同的实现方式。先把统一的访问方式写出来,这种访问方式应用于该命题下述的所有模式。

namespace CSharpTest
{
   
    class Program
    {
   
        static void Main(string[] args)
        {
            Singleton s = Singleton.GetInstance();
        }
    }
}

饿汉模式

  意思是,在该类装载时构建类的单例。(类的装载可以粗浅的理解为发生在程序启动时,Main之前)也就是说,这个单例跟你什么时候用,是否要用无关,只要运行程序,这个单例就存在了。这样做的坏处是如果程序初始化时要载入的资源过多时显然这种方式又提高了加载的负担,其次如果没有使用到的话也浪费了内存。

namespace CSharpTest
{
    public class Singleton
    {
        //私有化构造函数  使得外部无法构造类的实例
        private Singleton() { }
        //定义实例对象时便创建实例
        private static Singleton _instance = new Singleton();
        //提供全局访问点
        public static Singleton GetInstance()
        {
            return _instance;
        }
    }
}

懒汉模式

  意思是,在该类的单例被使用时构造类的单例。它相比饿汉模式更加灵活,所以应用更为广泛。

基本模式(单线程模式)

  在单线程中,只需做如下定义:

namespace CSharpTest
{
    public class Singleton
    {
        //私有化构造函数  使得外部无法构造类的实例
        private Singleton() { }
        //定义一个空的单例对象
        private static Singleton _instance;
        //提供全局访问点
        public static Singleton GetInstance()
        {
            //第一次访问时会创建实例
            if (_instance == null)
                _instance = new Singleton();
            return _instance;
        }
    }
}
多线程模式

  在多线程的程序中,构造单例的方式要发生什么变化呢?我们来依据单线程模式构造单例的代码来分析:全局访问方法内提供了如下的判断条件:

if (_instance == null)
    _instance = new Singleton();

  这会引发什么问题?以两个线程情况为例。当两个线程运行到这里时,可能线程1刚经过判断还没创建实例时,线程2就也已经通过判断要创建实例了,这会造成两个线程都创建了实例,这就违背了我们单例模式的初衷。所以我们要对其进行“加锁”,进行争用条件判断。即谁先来的谁先访问,我访问的时候你不许访问,我访问完了你再访问。

实现思路如下:
  这里使用一个辅助对象(必须是引用类型)充当锁ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值