设计模式-单例模式
单例模式是一种创建型设计模式,让你能够保证一个类有且只用一个实例,并提供一个访问该实例的全局节点。
作用:
- 保证一个类只有一个实例。 如果你创建了一个对象,同时过了一会儿后再决定创建一个新对象,这时获取的是已创建的对象,而不是一个新对象。
- 为该实例提供一个全局访问节点。
创建步骤:
- 将默认构造函数设为私有,防止其它对象外部实例化。
- 新建一个静态构造方法作为构造函数。该函数会调用私有构造函数来创建对象,并将其保存在一个静态成员变量中。此后外部的任何调用都将返回这一缓存对象。
饿汉式
下面的写法叫做饿汉式单例模式,原因:因为他想把对象提前New出来
,这样在外部第一次获取这个实例就是已经存在的,可以理解它饿,提前New了对象出来。
public class Singleton {
private static Singleton instance=new Singleton();
//私有构造函数,防止外部实例化
private Singleton() { }
//提供给外部调用的方法
public static Singleton GetInstance() {
return instance;
}
}
懒汉式
之所以叫懒汉式,可以理解它懒,如果外部第一次调用的时候发现该单例为null,然后去实例化。
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
(线程不安全) ,当多个线程执行getInstance()
方法时,可能一个线程执行到了if (instance == null)
还没有往下执行,第二个进程也开始执行if (instance == null)
这就导致最后有两个实例对象。
两者的区别:
两者只是在什么时候初始化的时候存在区别,饿汉式是提前初始化,懒汉式是在调用的时候是否为null,空则初始化,否则直接调用。
但是这里要注意:在Unity中不支持多线程,在Unity中使用的多线程实际上是C#中的多线程,而不是Unity中的多线程,Unity中是在主线程下运行的,还有协程的伪线程,(和线程不同)
解决方法:
加锁,必须加锁synchronized
才能保证单例,但加锁会影响效率。
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
两者应用的场景:
- 在场景中频繁调用的实例,在满足单例模式的需求后,可以将其实现为饿汉式单例模式,在场景开始就已经New出来,(提前加载)
- 在调用不那么频繁,可以使用懒汉式,在加载的时候判断单例是否为null。
- 以上都需要满足这里类是否可以写为单例模式供外部调用。