本文内容:
- 什么是单例模式
- 为什么要用单例模式基类
- 代码示例
什么是单例模式
提示:面向初学者理解教学,仅提供简单易懂的简单理解
在编程过程中, 有些类会被经常调用.
如果不使用单例模式, 在别处调用该类的方法时, 需要实例化该类.
多次实例化类, 会消耗一定的性能资源, 如果系统足够复杂, 需要调用的地方足够多,就会造成大量的资源浪费
而单例模式, 就可以保证类实例化一次 , 并且可以让全局获取该实例.
如果不使用单例模式
如果使用单例模式
单例模式代码解析
public class PlayerManager {
private static PlayerManager instance;
public static PlayerManager GetInstance() {
if (instance == null) {
instance = new PlayerManager();
return instance;
}
return instance;
}
public void Test(){}
}
这种写法在被调用的时候实例化类, 称为懒汉式,
外部调用 GetInstance();
如果没有实例化, 则实例化该类, 然后返回该类出去, 如果实例化过了, 则直接返回该类.
虽然外部并没有实例化该类, 但是却得到了该类,这样无论外部获得多少次该类, 都用的是同一个类,如果类里存有数据, 则访问, 修改的也是同一个数据.
外部调用示例
PlayerManager pm = PlayerManager .GetInstance();
pm.Test();
//或者写成
PlayerManager.GetInstance().Test();
另一种写法
public class ObjectManager {
private static ObjectManager instance = new ObjectManager();
public static ObjectManager Instance => instance;
public void Test(){}
}
外部调用示例
ObjectManager pm = ObjectManager.Instance;
pm.Test();
//或者写成
ObjectManager .Instance.Test();
在类加载时就初始化实例, 称为饿汉式.
两种方式略有不同, 对于初学者来说不好理解, 可以自行查找相关知识 , 本文仅介绍单例模式的使用和意义.
为什么要用单例模式基类
我们先举个简单的例子, 引出原因
//=============================================================
public class PlayerManager {
private static PlayerManager instance;
public static PlayerManager GetInstance() {
if (instance == null) {
instance = new PlayerManager();
return instance;
}
return instance;
}
}
//———————————————-
public class PlayerManagerTO {
private static PlayerManagerTO instance;
public static PlayerManagerTO GetInstance() {
if (instance == null) {
instance = new PlayerManagerTO();
return instance;
}
return instance;
}
}
//=============================================================
public class ObjectManager {
private static ObjectManager instance = new ObjectManager();
public static ObjectManager Instance => instance;
}
//———————————————-
public class ObjectManagerTO {
private static ObjectManagerTO instance = new ObjectManagerTO();
public static ObjectManagerTO Instance => instance;
}
以上是两种写法的4 个单例类, 可以直观的观察到, 如果有多个单例类, 我们需要重复写单例的代码, 并且这些代码的内容几乎相同 , 唯一不同的地方是以下框选位置


通过上图框选可以看出, 除了类名不同外 , 剩下的完全相同, 看到这可能就会有想到, 如果有一个占位符, 当使用的时候,把占位符改成需要的类名, 就可以解决所有单例类,需要重复写单例代码的问题了
基于以上的想法, 我们粗暴的进行改造
public class BaseManagerL<T> where T :new() {
private static T instance;
public static T GetInstance() {
if (instance == null) {
instance = new T();
return instance;
}
return instance;
}
}
public class BaseManager<T> where T: new() {
private static T instance = new T();
public static T Instance => instance;
}
我们把所有类名的地方, 都改成了泛型T 于是我们的单例类就变成了这样
public class PlayerManager :BaseManager<PlayerManager >
{
public void Test() { }//这个只是举例子要用的方法
}
public class PlayerManagerTO : BaseManagerL<PlayerManagerTO > {
public void Test() { }//这个只是举例子要用的方法
}
变得非常简单 ,调用方法没有变化, 也就是只需要一个单例基类, 别的单例类继承该基类, 就可以直接变成单例类, 如果想要继承别的类, 比如说Unity 中需要继承的Mono类, 我会在下篇文章讲解
结尾
我们已经解决了如下问题, 本文只帮助初学者理解单例, 尽可能的简化了语句, 如果需要进一步了解单例, 可以去搜索相关问题, 相信看了本文 , 会对单例有一个清晰的了解.
- 什么是单例模式
- 为什么要用单例模式基类

