• Unity 游戏框架搭建 单例的模板


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

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

    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,那么以上这些代码要复制粘贴好多遍。重复的代码太多!!!想要把重复的代码抽离出来,怎么办?答案是引入泛型。实现如下:

    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日补充:这么说有点不够yan'jin。因为泛型本身不是一个类型,那该怎么办呢?答案是使用反射。实现如下:

    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#程序中都是通用的。其测试用例如下所示:

    using QFramework;  
    // 1.需要继承QSingleton。
    // 2.需要实现非public的构造方法。
    public class XXXManager : QSingleton<XXXManager> {  
        private XXXManager() {
            // to do ...
        }
    }
    
    
    public static void main(string[] args)  
    {
        XXXManager.Instance().xxxyyyzzz();
    }

    总结

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

    以上都源自:http://liangxiegame.com/unity-you-xi-kuang-jia-da-jian-er/  谢谢

  • 相关阅读:
    编写高质量代码改善C#程序的157个建议——建议7: 将0值作为枚举的默认值
    编写高质量代码改善C#程序的157个建议——建议6: 区别readonly和const的使用方法
    编写高质量代码改善C#程序的157个建议——建议5: 使用int?来确保值类型也可以为null
    编写高质量代码改善C#程序的157个建议——建议4: TryParse比Parse好
    基于cookie实现用户验证
    页面分页自定义插件
    DOM详习讲解
    HTML标签详细讲解
    Tornado模板配置
    biginteger转Long
  • 原文地址:https://www.cnblogs.com/lfy007/p/5292148.html
Copyright © 2020-2023  润新知