Unity 游戏框架搭建 (二) 单例的模板
来源:互联网 发布:linux进去编辑模式 编辑:程序博客网 时间:2024/06/07 21:38
上一篇文章中说到的manager of managers,其中每个manager都是单例的实现,当然也可以使用静态类实现,但是相比于静态类的实现,单例的实现更为通用,可以适用大多数情况。
如何设计这个单例的模板?
先分析下需求,当设计一个manager时候,我们希望整个程序只有一个该manager对象实例,一般马上能想到的实现是这样的:
如果一个游戏需要10个各种各样的manager,那么以上这些代码要复制粘贴好多遍。重复的代码太多!!!想要把重复的代码抽离出来,怎么办?答案是引入泛型。实现如下:
为了可以被继承,静态实例和构造方法都使用protect修饰符。以上的问题很显而易见,那就是不能new一个泛型(3月9日补充:并不是不能new一个泛型,参考:[new一个泛型的实例,编译失败了,为什么?-CSDN论坛-CSDN.NET-中国最大的IT技术社区](http://bbs.csdn.net/topics/390911693)),(4月5日补充:有同学说可以new一个泛型的实例,不过要求改泛型提供了public的构造函数,好吧,这里不用new的原因是,无法显示调用private的构造函数)。因为泛型本身不是一个类型,那该怎么办呢?答案是使用反射。实现如下:
以上就是最终实现了。这个实现是在任何C#程序中都是通用的。其测试用例如下所示:
总结
这个单例的模板是平时用得比较顺手的工具了,其实现是在其他的框架中发现的,拿来直接用了。反射的部分可能会耗一些性能,但是只会执行一次。在中可能会需要继承MonoBehaviour的单例,因为很多游戏可能会只创建一个GameObject,用来获取MonoBehaviour的生命周期,这些内容会再下一讲中介绍:)
附:[我的框架地址](https://github.com/liangxiegame/QFramework)
转载请注明地址:[凉鞋的笔记](http://liangxiegame.com/)
如何设计这个单例的模板?
先分析下需求,当设计一个manager时候,我们希望整个程序只有一个该manager对象实例,一般马上能想到的实现是这样的:
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
public
class
XXXManager {
private
static
XXXManager instance =
null
;
private
XXXManager {
// to do ...
}
public
static
XXXManager() {
if
(instance ==
null
)
{
instance =
new
XXXManager();
}
return
instance;
}
}
如果一个游戏需要10个各种各样的manager,那么以上这些代码要复制粘贴好多遍。重复的代码太多!!!想要把重复的代码抽离出来,怎么办?答案是引入泛型。实现如下:
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Reflection;
namespace
QFramework {
public
abstract
class
QSingleton<T> where T : QSingleton<T>
{
protected
static
T instance =
null
;
protected
QSingleton()
{
}
public
static
T Instance()
{
if
(instance ==
null
)
{
// 如何new 一个T???
}
return
instance;
}
}
}
为了可以被继承,静态实例和构造方法都使用protect修饰符。以上的问题很显而易见,那就是不能new一个泛型(3月9日补充:并不是不能new一个泛型,参考:[new一个泛型的实例,编译失败了,为什么?-CSDN论坛-CSDN.NET-中国最大的IT技术社区](http://bbs.csdn.net/topics/390911693)),(4月5日补充:有同学说可以new一个泛型的实例,不过要求改泛型提供了public的构造函数,好吧,这里不用new的原因是,无法显示调用private的构造函数)。因为泛型本身不是一个类型,那该怎么办呢?答案是使用反射。实现如下:
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Reflection;
/// <summary>
/// 1.泛型
/// 2.反射
/// 3.抽象类
/// 4.命名空间
/// </summary>
namespace
QFramework {
public
abstract
class
QSingleton<T> where T : QSingleton<T>
{
protected
static
T instance =
null
;
protected
QSingleton()
{
}
public
static
T Instance()
{
if
(instance ==
null
)
{
// 先获取所有非public的构造方法
ConstructorInfo[] ctors =
typeof
(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
// 从ctors中获取无参的构造方法
ConstructorInfo ctor = Array.Find(ctors, c => c.GetParameters().Length == 0);
if
(ctor ==
null
)
throw
new
Exception(
"Non-public ctor() not found!"
);
// 调用构造方法
instance = ctor.Invoke(
null
)
as
T;
}
return
instance;
}
}
}
以上就是最终实现了。这个实现是在任何C#程序中都是通用的。其测试用例如下所示:
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
using
QFramework;
// 1.需要继承QSingleton。
// 2.需要实现非public的构造方法。
public
class
XXXManager : QSingleton<XXXManager> {
private
XXXManager() {
// to do ...
}
}
public
static
void
main(
string
[] args)
{
XXXManager.Instance().xxxyyyzzz();
}
总结
这个单例的模板是平时用得比较顺手的工具了,其实现是在其他的框架中发现的,拿来直接用了。反射的部分可能会耗一些性能,但是只会执行一次。在中可能会需要继承MonoBehaviour的单例,因为很多游戏可能会只创建一个GameObject,用来获取MonoBehaviour的生命周期,这些内容会再下一讲中介绍:)
附:[我的框架地址](https://github.com/liangxiegame/QFramework)
转载请注明地址:[凉鞋的笔记](http://liangxiegame.com/)
0 0
- Unity 游戏框架搭建 (二) 单例的模板
- Unity 游戏框架搭建 (二) 单例的模板
- Unity 游戏框架搭建 (二) 单例的模板
- Unity 游戏框架搭建 (三) MonoBehaviour单例的模板
- Unity 游戏框架搭建 (三) MonoBehaviour单例的模板
- Unity 游戏框架搭建 (三) MonoBehaviour单例的模板
- Unity 游戏框架搭建 (三) MonoBehaviour单例的模板
- Unity 游戏框架搭建 (十三) 无需继承的单例的模板
- Unity 游戏框架搭建 (十三) 无需继承的单例的模板
- Unity 游戏框架搭建 (十三) 无需继承的单例的模板
- Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
- Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
- Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
- UNITY 单例模式的模板
- Unity 游戏框架搭建 (十四) 优雅的QSignleton(零) QuickStart
- Unity 游戏框架搭建 (十五) 优雅的QChain (零)
- Unity 游戏框架搭建--简易有限状态机
- Unity 游戏框架搭建 (一) 概述
- Android 中最简单的实现 HTML(H5)调用native原生页面的方法
- jQuery 获取 Select 下拉框的信息
- 冯.诺伊曼结构、哈佛结构、超级哈佛结构之间的异同
- 用js实现按钮加减,减到0停止
- GIT 分支管理:创建与合并分支、解决合并冲突
- Unity 游戏框架搭建 (二) 单例的模板
- Ionic持久化存储(二)
- apache-commons-net Ftp 进行文件、文件夹的上传下载及日志的输出
- MPEG-4 Audio 关于esds 记录
- android 不经意遇到的一些小问题汇总
- Unity 游戏框架搭建 (三) MonoBehaviour单例的模板
- c# 创建属性值对数据结构类型xml文件工具类
- cpio制作initramfs
- JAVA CAS原理深度分析