之前的文章中介绍的 游戏框架搭建(二) 单例的模板
http://www.manew.com/thread-89635-1-1.html
和Unity游戏框架搭建(三) MonoBehaviour单例的模板
http://www.manew.com/thread-89636-1-1.html有一些
问题。
存在的问题:
- 只要继承了单例的模板就无法再继承其他的类。
虽然单例继承其他类是比较脏的设计,但是难免会遇到不得不继承的时候。没有最好的设计,只有最合适的设计。
解决方案:
- 首先实现单例的类从使用方式上应该不变,还是
[C#]
纯文本查看
复制代码
|
XXX.Instance.ABCFunc()
|
之前的单利的模板代码如下所示:
[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
38
39
40
41
42
43
44
|
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 mInstance =
null
;
protected
QSingleton()
{
}
public
static
T Instance
{
get
{
if
(mInstance ==
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!"
);
// 调用构造方法
mInstance = ctor.Invoke (
null
)
as
T;
}
return
mInstance;
}
}
public
void
Dispose()
{
mInstance =
null
;
}
}
}
|
按照以前的方式,如果想实现一个单例的代码应该是这样的:
[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();
}
|
如果我想XXXManager继承一个BaseManager代码就变成这样了
[C#]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
|
using
QFramework;
// 1.需要继承QSingleton。
// 2.需要实现非public的构造方法。
public
class
XXXManager : BaseManager {
private
XXXManager() {
// to do ...
}
}
public
static
void
main(
string
[] args)
{
XXXManager.Instance().xxxyyyzzz();
}
|
这样这个类就不是单例了,怎么办?
答案是通过C#的属性。
[C#]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
using
QFramework;
// 1.需要继承QSingleton。
// 2.需要实现非public的构造方法。
public
class
XXXManager : BaseManager {
private
XXXManager() {
// to do ...
}
public
static
XXXManager Instance {
get
{
return
QSingletonComponent<XXXManager>.Instance;
}
}
}
public
static
void
main(
string
[] args)
{
XXXManager.Instance().xxxyyyzzz();
}
|
好了,又看到陌生的东西了,QSingletonComponent是什么?
和之前的单例的模板很相似,贴上代码自己品吧...
[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
38
39
40
41
|
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Reflection;
/// <summary>
/// 组合方式实现单例子
/// </summary>
namespace
QFramework {
/// <summary>
/// class是引用类型
/// </summary>
public
class
QSingletonComponent<T> where T :
class
{
protected
static
T mInstance =
null
;
public
static
T Instance
{
get
{
if
(mInstance ==
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!"
);
// 调用构造方法
mInstance = ctor.Invoke (
null
)
as
T;
}
return
mInstance;
}
}
public
static
void
Dispose()
{
mInstance =
null
;
}
}
}
|
这样无法继承的问题就解决啦。
缺点是:相比于QSingleton,QSingletonComponent在使用时候多了一次函数调用,不过做中小型项目应该可以应付了。
介绍完毕,睡觉了。。。
附:我的框架地址:https://github.com/liangxiegame/QFramework
转载请注明地址:凉鞋的笔记 liangxiegame.com