Skip to content

Latest commit

 

History

History
230 lines (169 loc) · 4.5 KB

单例模式.md

File metadata and controls

230 lines (169 loc) · 4.5 KB

单例模式

[TOC]

设计模式

该类在程序中是唯一的,无需反复实例化就能调用类中的成员(直接用类名.单例 的形式访问到这个类)。

在一个非静态类声明一个class类型的字段,这个字段指向类本身,用static修饰。

用于全局变量、其他脚本需要调用的变量 如UI,对象池,角色属性,bgm管理

优点

只在第一次请求时被创建,只存在一个对象进行运作

节约内存 节省性能 便于链接游戏各个模块

基础单例实现

继承于MonoBehaviour

1静态字段访问 将Instance定义为公共字段

public class Singleton : MonoBehaviour{

	public static Singleton Instance;					//静态实例

	private void Awake()
	{
  	  												//若已经存在,删除
   	 if(Instance != null && Instance != this)
   	 {
    	    Destory(this);
	        return;
   	 }
   	 else
   	 {
        	Instance = this;							//创建唯一实例
   		}
    	DontDestoryOnLoad(this);
	}

    
	private void onApplicationQuit()
	{
   	 if(Instance! =null)
   	 {
        	Destory(this);								//销毁实例
    	}
	}
    
    public void Method()
    {
        //code...
    }
}

在其他脚本调用

Singleton.Instance.Method();

unity另一种写法

(更规范吗?

类的构造函数被设置成私有,只能在类的内部访问,提供一个静态方法使得其他类可以通过调用这个方法来获取该类的唯一实例。

public class Singleton : Monobehaviour
{
    //私有
    private static Singleton instance;		
    
    //静态访问方法
    public static Singleton Instance
    {
        get{
            if(instance==null)
            {
                instance = FindObjectOfType(typeof(Singleton)) as Singleton;
                //instance = new GameObject("Singleton").AddComponent<Singleton>();
            }
            
            return instance;
            
        }
    }
}

其他类通过Instance()方法获取唯一实例。如果该实例不存在,它将在内部创建,否则直接返回已有实例

2

一个单例游戏设置脚本的例子

using UnityEngine;

public class GameSetting : MonoBehaviour
{
    public static GameSetting instance;
    
    public float voice;
    public float light;
    
    private void Awake()
    {
        //保存单例
        instance = this;
    }
    
    	//各种方法
    public void set1()
    {
        
    }
    public void set2()
    {
        
    }
}
不继承

因为不继承自monobehaviour,所以不用挂在GameObject上

public class Singleton
{
    public static Singleton instance;
    
    public static Singleton Instance
    {
        get
        {
            if(null == instance)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
    
    public void Method()
    {
        //code
    }
}

泛型单例

项目中存在多个单例模式的类时,可以用单例模式的泛型实现

泛型:允许延迟编写类或方法中的编程元素或数据类型的规范

​ 定义一个类,这个类中某些字段的类型是待确定的(T),可以在构造的时候再确定下来。

class Singleton<T> where T: class,new()//约束了T的类型
{
    private static T instance;			//指定了T类型
    
    private static readonly object locker=new object();
    
    public static T getInstance()
    {                                                                                                                                                                                                                                                 
        if(instance == null)
        {
            //这里用了lock语句保证只实例化一次
            lock(locker)
            {
                if(instance == null)
                {
                    instance = new T();
                }
            }
        }
        return instance;
    }
}

在其他类中,继承上面的类就可以实现单例化

public class myclass : Singleton<myclass>
{
    public void sample()
    {
        //code
    }
}

main中调用

myclass.getInstance().sample();

另一种方法

class muclass
{
    public static myclass getInstance()
    {
        return Singleton<myclass>.getInstance();
    }
    public void sample()
    {
        //code
    }
}