查看: 2241|回复: 0
打印 上一主题 下一主题

[教程] 3d素材unity 游戏框架搭建 (二) 单例的模板

[复制链接]

25

主题

1

听众

314

积分

设计实习生

Rank: 2

纳金币
48
精华
0
跳转到指定楼层
楼主
发表于 2016-8-19 18:40:18 |只看该作者 |倒序浏览
哈喽,欢迎来到汇宝盆,首先非常感谢作者凉鞋的笔记分享这篇文章,上一篇文章中说到的manager of managers,其中每个manager都是单例的实现,当然也可以使用静态类实现,但是相比于静态类的实现,单例的实现更为通用,可以适用大多数情况。
如何设计这个单例的模板?
  先分析下需求,当设计一个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一个泛型(39日补充:并不是不能new一个泛型,参考:new一个泛型的实例,编译失败了,为什么?-CSDN论坛-CSDN.NET-中国最大的IT技术社区),(45日补充:有同学说可以new一个泛型的实例,不过要求改泛型提供了public的构造函数,好吧,这里不用new的原因是,无法显示调用private的构造函数)。因为泛型本身不是一个类型,那该怎么办呢?答案是使用反射。实现如下:
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();
}
总结
  这个单例的模板是平时用得比较顺手的工具了,其实现是在其他的框架中发现的,拿来直接用了。反射的部分可能会耗一些性能,但是只会执行一次。在3d素材unity中可能会需要继承MonoBehaviour的单例,因为很多游戏可能会只创建一个GameObject,用来获取MonoBehaviour的生命周期,这些内容会再下一讲中介绍
看完了这篇分享,是不是对3d素材unity游戏搭建有一定的了解了呢,如果能给您带来一些帮助,汇宝盆万分荣幸!更多精彩可以进群讨论分享纳金网汇宝盆交流⑤群 341024464。
本文转载自网络,谢谢作者分享。

本帖被以下淘专辑推荐:

  • · 教程|主题: 5, 订阅: 1
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖1 收藏收藏1 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-25 22:58 , Processed in 0.099264 second(s), 33 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部