zoukankan      html  css  js  c++  java
  • 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

    更多内容

  • 相关阅读:
    python 字符串常用操作
    markdown 基础语法
    网络安全入门的16个基本问题
    Linux中20个crontab例子
    使用python爬取一个网页里表格的内容
    浅谈python的深浅拷贝
    Linux中设置普通用户可以su和sudo
    iptables四表五链
    CentOS7编译安装NFS
    源码安装csvn
  • 原文地址:https://www.cnblogs.com/liangxiegame/p/Unity-you-xi-kuang-jia-da-jian-shi-san-wu-xu-ji-ch.html
Copyright © 2011-2022 走看看