美文网首页
Unity 游戏框架搭建 (二) 单例的模板

Unity 游戏框架搭建 (二) 单例的模板

作者: _橙瘾 | 来源:发表于2017-11-13 08:53 被阅读0次

    上一篇文章中说到的manager of managers,其中每个manager都是单例的实现,当然也可以使用静态类实现,但是相比于静态类的实现,单例的实现更为通用,可以适用大多数情况。

    如何设计这个单例的模板?

    先分析下需求,当设计一个manager时候,我们希望整个程序只有一个该manager对象实例,一般马上能想到的实现是这样的:

    publicclassXXXManager {

    privatestaticXXXManager instance =null;

    privateXXXManager {

    // to do ...

    }

    publicstaticXXXManager() {

    if(instance ==null)

    {

    instance =newXXXManager();

    }

    returninstance;

    }

    }

    如果一个游戏需要10个各种各样的manager,那么以上这些代码要复制粘贴好多遍。重复的代码太多!!!想要把重复的代码抽离出来,怎么办?答案是引入泛型。实现如下:

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Text;

    usingSystem.Reflection;

    namespaceQFramework {

    publicabstractclassQSingleton where T : QSingleton

    {

    protectedstaticT instance =null;

    protectedQSingleton()

    {

    }

    publicstaticT Instance()

    {

    if(instance ==null)

    {

    // 如何new 一个T???

    }

    returninstance;

    }

    }

    }

    为了可以被继承,静态实例和构造方法都使用protect修饰符。以上的问题很显而易见,那就是不能new一个泛型(3月9日补充:并不是不能new一个泛型,参考:[new一个泛型的实例,编译失败了,为什么?-CSDN论坛-CSDN.NET-中国最大的IT技术社区](http://bbs.csdn.net/topics/390911693)),(4月5日补充:有同学说可以new一个泛型的实例,不过要求改泛型提供了public的构造函数,好吧,这里不用new的原因是,无法显示调用private的构造函数)。因为泛型本身不是一个类型,那该怎么办呢?答案是使用反射。实现如下:

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.Text;

    usingSystem.Reflection;

    ///

    /// 1.泛型

    /// 2.反射

    /// 3.抽象类

    /// 4.命名空间

    ///

    namespaceQFramework {

    publicabstractclassQSingleton where T : QSingleton

    {

    protectedstaticT instance =null;

    protectedQSingleton()

    {

    }

    publicstaticT 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)

    thrownewException("Non-public ctor() not found!");

    // 调用构造方法

    instance = ctor.Invoke(null)asT;

    }

    returninstance;

    }

    }

    }

    以上就是最终实现了。这个实现是在任何C#程序中都是通用的。其测试用例如下所示:

    usingQFramework;

    // 1.需要继承QSingleton。

    // 2.需要实现非public的构造方法。

    publicclassXXXManager : QSingleton {

    privateXXXManager() {

    // to do ...

    }

    }

    publicstaticvoidmain(string[] args)

    {

    XXXManager.Instance().xxxyyyzzz();

    }

    总结

    这个单例的模板是平时用得比较顺手的工具了,其实现是在其他的框架中发现的,拿来直接用了。反射的部分可能会耗一些性能,但是只会执行一次。在Unity中可能会需要继承MonoBehaviour的单例,因为很多游戏可能会只创建一个GameObject,用来获取MonoBehaviour的生命周期,这些内容会再下一讲中介绍:)

    附:[我的框架地址](https://github.com/liangxiegame/QFramework)

    转载请注明地址:[凉鞋的笔记](http://liangxiegame.com/)

    相关文章

      网友评论

          本文标题:Unity 游戏框架搭建 (二) 单例的模板

          本文链接:https://www.haomeiwen.com/subject/hmuamxtx.html