1.non-MonoBehaviour 单例模式泛型基类

一、单例模式

1. 什么是单例模式

单例模式(Singleton Pattern)是一种设计模式。

作用:保证一个类在程序运行期间只有一个实例,并提供统一访问入口。

例如游戏中的管理类:

  • GameManager(游戏管理)
  • AudioManager(音频管理)
  • UIManager(UI管理)
  • DataManager(数据管理)
  • ResourceManager(资源管理)
    这些对象通常整个游戏只需要一个。

2. 为什么需要单例模式

如果普通创建对象:

复制代码
GameManager gm1 = new GameManager();
GameManager gm2 = new GameManager();

会产生多个管理对象。可能导致:

  • 数据不统一
  • 多个对象重复执行逻辑
  • 增加内存开销

二、非 MonoBehaviour 单例模式

1. 为什么 Manager 不继承 MonoBehaviour

Unity 中继承 MonoBehaviour 的类:

  • 需要挂载到 GameObject

  • 由 Unity 管理生命周期

  • 可以使用 Awake、Start、Update 等函数
    例如:

    public class Player : MonoBehaviour
    {

    }

2. 非 MonoBehaviour 单例特点

优点:

  • 不需要创建 GameObject
  • 不依赖 Unity 生命周期
  • 代码结构更加清晰
  • 适合程序框架层
    缺点:
  • 不能使用 Awake、Start、Update
  • 需要自己管理生命周期

三、泛型单例基类

1. 为什么使用泛型基类

如果每个 Manager 都单独写单例:每个管理器都需要重复编写。

2. 泛型单例基类实现

复制代码
public abstract class Singleton<T> where T : class, new()
{
    private static T instance;
    public static T Instance
    {
        get
        {
            instance ??= new T();
            return instance;
        }
    }
}

四、泛型约束

1. class 约束

复制代码
where T : class

表示:T 必须是引用类型。

原因:单例对象需要通过实例引用管理。

2. new() 约束

复制代码
where T : new()

表示:T 必须拥有无参数构造函数。因为内部需要:new T()创建对象。

五、Instance 属性

1. 作用

Instance 是单例访问入口。

第一次访问:

复制代码
Instance
 ↓
判断对象是否存在
 ↓
不存在
 ↓
创建对象
 ↓
返回对象

之后访问:

复制代码
Instance
 ↓
已有对象
 ↓
直接返回

2. 为什么使用属性

推荐:GameManager.Instance;

不推荐:GameManager.GetInstance();

原因:Instance 表示获取对象,更符合 C# 属性设计习惯。

六、具体 Manager 使用方式

1. 创建管理类

复制代码
public class GameManager : Singleton<GameManager>
{

}

继承:Singleton<GameManager>

即可拥有:GameManager.Instance

2. 添加功能

复制代码
public class AudioManager : Singleton<AudioManager>
{
    public void PlayMusic()
    {
        Debug.Log("播放音乐");
    }
}

调用:AudioManager.Instance.PlayMusic();

七、非 MonoBehaviour 单例注意事项

1. 不能使用 Unity 生命周期

不能:

复制代码
Awake()
Start()
Update()

如果需要初始化:

可以提供Initialize()

例如:GameManager.Instance.Initialize();

2. 避免过度使用

单例虽然方便:

复制代码
XXXManager.Instance

但是大量使用会造成:

  • 类之间耦合增加
  • 后期修改困难
    只用于真正需要全局唯一的对象。
相关推荐
吃一碗粉只付一碗钱19 小时前
16-SqlSugar多库ConfigId与按实体选连接
sqlserver·c#
rockey62720 小时前
AScript之字符串模板
c#·.net·script·expression·动态脚本
锋行天下20 小时前
Langgraph-cli 本地构建失败,改用服务器docker构建的流程
人工智能·前端框架·全栈
will_net21 小时前
Redis集群部署+Redis 链接地址放入Aollo +c#项目接入Redis
redis·c#·bootstrap
狂潮lister1 天前
🚀 《掘金・挖矿小精灵》完整产品与系统架构设计 & V1.3‑LD‑M 落地工程设计文档(**封档版**)
前端·架构·前端框架
郝学胜-神的一滴1 天前
AI 编程智能体 22:解析器赋能与实战落地全指南
人工智能·程序人生·游戏·unity·游戏引擎
BuHuaX1 天前
Lua 与 ToLua:运行机制及热更新原理
开发语言·unity·junit·c#·lua
asdzx671 天前
C# 操作 PDF 元数据:从属性写入到字段提取的完整流程
前端·pdf·c#
氷凌公子1 天前
算法与UI拆分中遇到的问题及解决方式
c#·onnx·yolov26