🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
之前的文章中介绍的 《Unity 游戏框架搭建 (二) 单例的模板》 和 《Unity 游戏框架搭建 (三) MonoBehaviour单例的模板》有一些问题。 ## 存在的问题: * 只要继承了单例的模板就无法再继承其他的类。 虽然单例继承其他类是比较脏的设计,但是难免会遇到不得不继承的时候。没有最好的设计,只有最合适的设计。 ## 解决方案: * 首先实现单例的类从使用方式上应该不变,还是 ```cs XXX.Instance.ABCFunc() ``` 之前的单利的模板代码如下所示: ```cs 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; } } } ``` 按照以前的方式,如果想实现一个单例的代码应该是这样的: ```cs 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代码就变成这样了 ```cs using QFramework; // 1.需要继承QSingleton。 // 2.需要实现非public的构造方法。 public class XXXManager : BaseManager { private XXXManager() { // to do ... } } public static void main(string[] args) { XXXManager.Instance().xxxyyyzzz(); } ``` 这样这个类就不是单例了,怎么办? 答案是通过 C# 的属性。 ```cs 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 是什么? 和之前的单例的模板很相似,贴上代码自己品吧... ```cs 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 在使用时候多了一次函数调用,不过做中小型项目应该可以应付了。 介绍完毕,睡觉了。。。 ## 欢迎讨论! 转载请注明地址:凉鞋的笔记:[liangxiegame.com](http://liangxiegame.com) ## 更多内容 * QFramework 地址:[https://github.com/liangxiegame/QFramework](https://github.com/liangxiegame/QFramework) * QQ 交流群:[623597263](http://shang.qq.com/wpa/qunwpa?idkey=706b8eef0fff3fe4be9ce27c8702ad7d8cc1bceabe3b7c0430ec9559b3a9ce66) * **Unity 进阶小班**: * 主要训练内容: * 框架搭建训练(第一年) * 跟着案例学 Shader(第一年) * 副业的孵化(第二年、第三年) * 权益、授课形式等具体详情请查看[《小班产品手册》](https://liangxiegame.com/master/intro):https://liangxiegame.com/master/intro * 关注公众号:liangxiegame 获取第一时间更新通知及更多的免费内容。 ![](http://file.liangxiegame.com/38eccb55-40b2-4845-93d6-f5fb50ff9492.png)