• Unity 游戏框架搭建 2017 (十三) 无需继承的单例的模板


    之前的文章中介绍的 《Unity 游戏框架搭建 (二) 单例的模板》 和 《Unity 游戏框架搭建 (三) MonoBehaviour单例的模板》有一些问题。

    存在的问题:

    • 只要继承了单例的模板就无法再继承其他的类。

    虽然单例继承其他类是比较脏的设计,但是难免会遇到不得不继承的时候。没有最好的设计,只有最合适的设计。

    解决方案:

    • 首先实现单例的类从使用方式上应该不变,还是
      XXX.Instance.ABCFunc()

    之前的单利的模板代码如下所示:

    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;
            }
        }
    }

    按照以前的方式,如果想实现一个单例的代码应该是这样的:

    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代码就变成这样了

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

    这样这个类就不是单例了,怎么办?

    答案是通过 C# 的属性。

    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 是什么?

    和之前的单例的模板很相似,贴上代码自己品吧...

    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

    更多内容

  • 相关阅读:
    LayoutInflater作用及使用
    php学习-数组(一)
    jQuery中$.get、$.post、$.getJSON和$.ajax的用法
    input的onchange事件实际触发条件与解决方法
    input有许多,点击按钮使用form传递文本框的值
    CI分页器pagination的原理及实现
    form表单传递下拉框的Value和Text值,不适用Jquery传递
    Servlet实现文件上传(多文件)(三)
    Servlet实现文件上传(深度)(二)
    Servlet实现文件上传(简单)(一)
  • 原文地址:https://www.cnblogs.com/liangxiegame/p/Unity-you-xi-kuang-jia-da-jian-shi-san-wu-xu-ji-ch.html
Copyright © 2020-2023  润新知