浅谈单例

单例模式

1.个人思路

  • 1.业务需求

统一使用同一个对象(创建的对象为一个 使用的对象是同一个)

  • 2.业务思考
  1. 如何生成对象 保存对象
  2. 如何保证生成的对象唯一
  • 3.实现的方案
  1. 利用系统在需要用到对象前进行唯一 一次初始化
  2. 调用对象为空的时候 进行一次初始化 保存对象

2.保证生成的单例唯一

2.1 使用static让系统帮忙初始化

    `  public sealed class Singleton
     {
             private static readonly Singleton instance = new Singleton();

             private Singleton() { }

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

      }`

2.2 使用Unity的生命周期

`      public sealed class Singleton : MonoBehaviour {

              public static Singleton Instance { get; private set; }

              private void Awake()
              {
                      Instance = this;
              }

        }`

2.3 使用锁保证单例唯一

`     public sealed class Singleton {

    private static Singleton instance = null;
    private static readonly Object syuncLock = new Object();

    private Singleton() { }

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

2.4 使用字典保证生成的单例唯一

    ` 
public sealed class Singleton : ISingleton
{

    private Singleton() { }
}

public interface ISingleton {

}

 public class SingletonManager
{
   private static readonly ConcurrentDictionary<string, ISingleton> singletonDict = new ConcurrentDictionary<string, ISingleton>();

    public static T GetSingleton<T>() where T : class, ISingleton
    {
        string className = typeof(T).ToString();

        if (!singletonDict.ContainsKey(className))
        {
            ConstructorInfo[] constructorInfos = typeof(T).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic);
            ConstructorInfo constructorInfo = Array.Find(constructorInfos, c => c.GetParameters().Length == 0);
            if (constructorInfo == null)
            {
                throw new Exception("生成失败! 没有找到私有的构造函数");
            }
            T manager = constructorInfo.Invoke (null) as T;
            singletonDict.TryAdd(className, manager);
        }
        return singletonDict[className] as T;
    }
}`

2.5 综合考虑

 `     public class SingletonManager {

private static GameObject singletonManager;
private static readonly object syuncLock = new object();
private static readonly Dictionary<string, ISingleton> singletonDict = new Dictionary<string, ISingleton>();

public static T GetSingleton<T>() where T : class, ISingleton
{
    string className = typeof(T).ToString();

    if (!singletonDict.ContainsKey(className))
    {
        lock (syuncLock)
        {
            if (!singletonDict.ContainsKey(className))
            {
                T manager = null;
                if (typeof(T).IsSubclassOf(typeof(MonoBehaviour)))
                {
                    AddComponentScript<T>(className);
                }
                else
                {
                    AddScript(className, manager);
                }
            }
        }

    }
    return singletonDict[className] as T;
}

private static void AddComponentScript<T>(string className)
{
    if(singletonManager == null)
    {
        singletonManager = new GameObject("singletonManager");
        UnityEngine.Object.DontDestroyOnLoad(singletonManager);
    }
    Type type = typeof(T);
    singletonManager.AddComponent(type);
    singletonDict.Add(className, singletonManager.GetComponent(type) as ISingleton);
}

private static void AddScript<T>(string className, T manager) where T : class, ISingleton
{
    ConstructorInfo[] constructorInfos = typeof(T).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
    ConstructorInfo constructorInfo = Array.Find(constructorInfos, c => c.GetParameters().Length == 0);
    if (constructorInfo == null)
    {
        throw new Exception("生成失败! 没有找到私有的构造函数");
    }
    manager = constructorInfo.Invoke(null) as T;
    singletonDict.Add(className, manager);
}

}`

`public interface ISingleton
{

}`
原文地址:https://www.cnblogs.com/programmingAdorableNew/p/10344775.html