目录
一、介绍
二、普通的写法
三、继承的写法
五、静态构造函数的写法
四、Unity中的单例
结束
一、介绍
单例模式是很多程序员学习设计模式的第一个设计模式,主要是平时工作中会用到,另一个在23个设计模式中算比较简单一个,从字面意思上理解为一个类只有一个实例,并对外开放一个静态的访问属性,所以一般称之为单例模式。
在各种单例模式版本中,总结又以下共同点:
1.唯一的、私有的且无参的构造函数,这样不允许外部类进行实例化;
2.类是密封的,尽管这不是强制的,但是严格来讲从上一点来看密封类能有助于JIT的优化;
3.一个静态变量应该指向类的唯一实例;
4.一个公共的静态变量用于获得这个类的唯一实例(如果需要,应该创建它;
在设计模式六大原则中的 单一职责原则和开闭原则 的作用是要求对代码做一定的分类和约束,所以我不建议过多的使用单例模式,除非用在常用的一些公共管理类中,比如游戏开发中的 ,UIManager,另外是工具类,专门用来写一些算法的类,但是这种工具类直接用静态类,静态方法就可以了,用单例模式去调用会感觉非常的别扭。
二、普通的写法
将访问入口直接写在类的内部,并将类的构造函数设为私有,防止其他类进行实例化,并对外开放一个访问的入口,这个是网上很多帖子介绍单例常用的写法。
using System;
namespace 单例模式
{
internal class Program
{
static void Main(string[] args)
{
();
();
}
}
}
public class Monkey
{
private static Monkey instance = null;
public static Monkey Instance
{
get
{
if(instance == null)
instance = new Monkey();
return instance;
}
}
public void Robbery()
{
("抢你的食物");
}
private Monkey() { }
}
三、继承的写法
继承的写法就是专门写一个单例类,其他类如果想用单例模式直接继承就好了,同时缺点也出来了,那就是无法继承其他类了
using System;
namespace 单例模式
{
internal class Program
{
static void Main(string[] args)
{
();
();
}
}
}
public class Monkey : Singleton<Monkey>
{
public void Robbery()
{
("抢你的食物");
}
}
public abstract class Singleton<T> where T : new()
{
private static T _instance;
private static object mutex = new object();
public static T Instance
{
get
{
if (_instance == null)
{
lock (mutex)
{
if (_instance == null)
{
_instance = new T();
}
}
}
return _instance;
}
}
}
五、静态构造函数的写法
使用静态构造函数去实例化单例,同样也符合单例的特征,在使用上和其他的单例并不会有什么不同,相反还会更加的简洁优雅。
using System;
namespace 单例模式
{
internal class Program
{
static void Main(string[] args)
{
();
();
}
}
}
public class Monkey
{
public static Monkey Instance = null;
public void Robbery()
{
("抢你的食物");
}
static Monkey()
{
Instance = new Monkey();
}
private Monkey() { }
}
四、Unity中的单例
下面代码可以作为参考,如果继承了这个单例类,在调用时会自动实例化一个游戏物体,会跟随着场景移动,并防止在移动到其他场景时,又实例化出一个相同的游戏物体。
public class UnitySingleton<T> : MonoBehaviour where T : Component {
private static T _instance = null;
public static T Instance {
get {
if (_instance == null) {
_instance = FindObjectOfType(typeof(T)) as T;
if (_instance == null) {
GameObject obj = new GameObject();
_instance = (T)(typeof(T));
= ;
// = ;
= typeof(T).Name;
}
}
return _instance;
}
}
public virtual void Awake() {
DontDestroyOnLoad();
if (_instance == null) {
_instance = this as T;
}
else {
();
}
}
}
DontDestroyOnLoad 方法的使用,也可以使用下面代码
using UnityEngine;
public class GameManager : MonoBehaviour {
public static GameManager Instance;
private static bool origional = true;
private void Awake()
{
if (origional)
{
Instance = this as GameManager;
origional = false;
DontDestroyOnLoad();
}
else
{
Destroy();
}
}
}
在 GameManager 中如果还要添加其他的管理类,在 Start 方法中使用 AddComponent 方法添加就好了。
结束
如果这个帖子对你有所帮助,欢迎 关注 + 点赞 + 留言
end