美文网首页unity3D技术分享征服Unity3dUnity技术分享
Unity 游戏框架搭建 (十三) 无需继承的单例的模板

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

作者: 凉鞋的笔记 | 来源:发表于2017-11-07 10:05 被阅读85次

    之前的文章中介绍的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

    image

    output/writing/unity游戏框架搭建

    相关文章

      网友评论

        本文标题:Unity 游戏框架搭建 (十三) 无需继承的单例的模板

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