1-6设计模式之单例模式(Singleton)

1.6.1 模式意图:

对于游戏中的某些类来说,只有一个实例很重要,例如各种Manager管理类,在系统中多处可调用,且始终保持独一无二的特性,可以使用设计模式中的单例模式来完成这类任务。

1.6.2 模式概念:

属于创建型模式,确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。

1.6.3 模式元素:

  • 单例(Singleton、Singleton

1.6.4 代码示例:

A.常规版本

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }
         return instance;
      }
   }
}

B.泛型版本

public sealed class Singleton<T> where T : class, new()
{
    public const string Name = "Singleton";
    static Singleton() { }
    private Singleton() { }
    private static volatile T instance = null;
    private static readonly object syncLock = new object();

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncLock)
                {
                    if (instance == null)
                    {
                        instance = new T();
                    }
                }
            }
            return instance;
        }
    }
}

C.Lazy类版本
如果使用的是.NET 4(或更高版本),可以使用Lazy类型使延迟变得非常简单。

using System;

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
}

D.Unity版本

using UnityEngine;

public class SingletonMonoBehaviour<T> : MonoBehaviour where T : SingletonMonoBehaviour<T>
{
    static SingletonMonoBehaviour() { }
    protected SingletonMonoBehaviour() { }
    private static volatile T instance = null;

    public static T Instance
    {
        get
        {
            return instance;
        }
    }

    protected virtual void Awake()
    {
        instance = this as T;
    }
}

1.6.5 写法对比:

1.6.6 模式分析:

  • 只有一个实例,最大限度减少了内存的开销,避免频繁的创建和销毁实例。
  • 始终保持唯一实例,易于控制对该实例的访问途径。
  • 可全局共享访问

不足之处:

  • 不方便扩展
  • 如果大量使用单例,并更改单例类中某处,可能会造成牵一发而动全身的情况。

1.6.7 应用场景:

要求全局保持唯一的实例且可共享访问。

1.6.8 小结:

最好使用延迟加载的模式进行单例,避免在同一时间单例初始化过多造成性能瓶颈。在享受单例优点的同时,要减少系统多处使用单例的情况,降低因过多使用单例而导致后期维护成本过高。


更多设计模式详见:设计模式全家桶

发表评论