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. /// 1.泛型
  7. /// 2.反射
  8. /// 3.抽象类
  9. /// 4.命名空间
  10. ///
  11. namespace QFramework {
  12. public abstract class QSingleton where T : QSingleton
  13. {
  14. protected static T mInstance = null;

  15. protected QSingleton()

  16. {
  17. }

  18. public static T Instance

  19. {

  20. get {

  21. if (mInstance == null) {
  22. // 先获取所有非public的构造方法
  23. ConstructorInfo[] ctors = typeof(T).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic);
  24. // 从ctors中获取无参的构造方法
  25. ConstructorInfo ctor = Array.Find (ctors, c => c.GetParameters ().Length == 0);
  26. if (ctor == null)
  27. throw new Exception (“Non-public ctor() not found!”);
  28. // 调用构造方法
  29. mInstance = ctor.Invoke (null) as T;
  30. }

  31. return mInstance;

  32. }
  33. }

  34. public void Dispose()

  35. {
  36. mInstance = null;
  37. }
  38. }
  39. }

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

  1. using QFramework;
  2. // 1.需要继承QSingleton。
  3. // 2.需要实现非public的构造方法。
  4. public class XXXManager : QSingleton {
  5. private XXXManager() {
  6. // to do …
  7. }
  8. }

  9. public static void main(string[] args)

  10. {
  11. XXXManager.Instance().xxxyyyzzz();
  12. }

如果我想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. public static void main(string[] args)

  10. {
  11. XXXManager.Instance().xxxyyyzzz();
  12. }

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

答案是通过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.Instance;
  11. }
  12. }
  13. }

  14. public static void main(string[] args)

  15. {
  16. XXXManager.Instance().xxxyyyzzz();
  17. }

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

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Reflection;

  5. ///

  6. /// 组合方式实现单例子
  7. ///
  8. namespace QFramework {

  9. ///

  10. /// class是引用类型
  11. ///
  12. public class QSingletonComponent where T : class
  13. {
  14. protected static T mInstance = null;

  15. public static T Instance

  16. {

  17. get {

  18. if (mInstance == null) {
  19. // 先获取所有非public的构造方法
  20. ConstructorInfo[] ctors = typeof(T).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic);
  21. // 从ctors中获取无参的构造方法
  22. ConstructorInfo ctor = Array.Find (ctors, c => c.GetParameters ().Length == 0);
  23. if (ctor == null)
  24. throw new Exception (“Non-public ctor() not found!”);
  25. // 调用构造方法
  26. mInstance = ctor.Invoke (null) as T;
  27. }

  28. return mInstance;

  29. }
  30. }

  31. public static void Dispose()

  32. {
  33. mInstance = null;
  34. }
  35. }
  36. }

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

缺点是:相比于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 。