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

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

存在的问题:

  • 只要继承了单例的模板就无法再继承其他的类。虽然单例继承其他类是比较脏的设计,但是难免会遇到不得不继承的时候。没有最好的设计,只有最合适的设计。

解决方案:

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

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Reflection;
  5.  
  6. /// <summary>
  7. /// 1.泛型
  8. /// 2.反射
  9. /// 3.抽象类
  10. /// 4.命名空间
  11. /// </summary>
  12. namespace QFramework {
  13. public abstract class QSingleton<T> where T : QSingleton<T>
  14. {
  15. protected static T mInstance = null;
  16.  
  17. protected QSingleton()
  18. {
  19. }
  20.  
  21. public static T Instance
  22. {
  23.  
  24. get {
  25. if (mInstance == null) {
  26. // 先获取所有非public的构造方法
  27. ConstructorInfo[] ctors = typeof(T).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic);
  28. // 从ctors中获取无参的构造方法
  29. ConstructorInfo ctor = Array.Find (ctors, c => c.GetParameters ().Length == 0);
  30. if (ctor == null)
  31. throw new Exception ("Non-public ctor() not found!");
  32. // 调用构造方法
  33. mInstance = ctor.Invoke (null) as T;
  34. }
  35.  
  36. return mInstance;
  37. }
  38. }
  39.  
  40. public void Dispose()
  41. {
  42. mInstance = null;
  43. }
  44. }
  45. }

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

  1. using QFramework;
  2. // 1.需要继承QSingleton。
  3. // 2.需要实现非public的构造方法。
  4. public class XXXManager : QSingleton<XXXManager> {
  5. private XXXManager() {
  6. // to do ...
  7. }
  8. }
  9.  
  10.  
  11. public static void main(string[] args)
  12. {
  13. XXXManager.Instance().xxxyyyzzz();
  14. }

如果我想XXXManager继承一个BaseManager代码就变成这样了

  1. using QFramework;
  2. // 1.需要继承QSingleton。
  3. // 2.需要实现非public的构造方法。
  4. public class XXXManager : BaseManager {
  5. private XXXManager() {
  6. // to do ...
  7. }
  8. }
  9.  
  10.  
  11. public static void main(string[] args)
  12. {
  13. XXXManager.Instance().xxxyyyzzz();
  14. }

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

答案是通过C#的属性。

  1. using QFramework;
  2. // 1.需要继承QSingleton。
  3. // 2.需要实现非public的构造方法。
  4. public class XXXManager : BaseManager {
  5. private XXXManager() {
  6. // to do ...
  7. }
  8. public static XXXManager Instance {
  9. get {
  10. return QSingletonComponent<XXXManager>.Instance;
  11. }
  12. }
  13. }
  14.  
  15.  
  16. public static void main(string[] args)
  17. {
  18. XXXManager.Instance().xxxyyyzzz();
  19. }

好了,又看到陌生的东西了,QSingletonComponent是什么?

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Reflection;
  5.  
  6. /// <summary>
  7. /// 组合方式实现单例子
  8. /// </summary>
  9. namespace QFramework {
  10.  
  11. /// <summary>
  12. /// class是引用类型
  13. /// </summary>
  14. public class QSingletonComponent<T> where T : class
  15. {
  16. protected static T mInstance = null;
  17.  
  18. public static T Instance
  19. {
  20.  
  21. get {
  22. if (mInstance == null) {
  23. // 先获取所有非public的构造方法
  24. ConstructorInfo[] ctors = typeof(T).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic);
  25. // 从ctors中获取无参的构造方法
  26. ConstructorInfo ctor = Array.Find (ctors, c => c.GetParameters ().Length == 0);
  27. if (ctor == null)
  28. throw new Exception ("Non-public ctor() not found!");
  29. // 调用构造方法
  30. mInstance = ctor.Invoke (null) as T;
  31. }
  32.  
  33. return mInstance;
  34. }
  35. }
  36.  
  37. public static void Dispose()
  38. {
  39. mInstance = null;
  40. }
  41. }
  42. }

这样无法继承的问题就解决啦。

缺点是:相比于QSingleton,QSingletonComponent在使用时候多了一次函数调用,不过做中小型项目应该可以应付了。

介绍完毕,睡觉了。。。

欢迎讨论!

相关链接:

我的框架地址:https://github.com/liangxiegame/QFramework

教程源码:https://github.com/liangxiegame/QFramework/tree/master/Assets/HowToWriteUnityGameFramework/

QFramework &游戏框架搭建QQ交流群: 623597263

转载请注明地址:凉鞋的笔记http://liangxiegame.com/

微信公众号:liangxiegame

13.无需继承的单例的模板  - 图1

如果有帮助到您:

如果觉得本篇教程对您有帮助,不妨通过以下方式赞助笔者一下,鼓励笔者继续写出更多高质量的教程,也让更多的力量加入 QFramework 。