举例讲解C#编程中对设计模式中的单例模式的运用

2019-12-26 18:03:32丽君

菜鸟:怎样确保一个类只有一个实例了?

老鸟:那就让我帮你分析下,你创建类的实例会想到用什么方式来创建的呢?

新手:用new关键字啊,只要new下就创建了该类的一个实例了,之后就可以使用该类的一些属性和实例方法了

老鸟:那你想过为什么可以使用new关键字来创建类的实例吗?

菜鸟:这个还有条件的吗?........., 哦,我想起来了,如果类定义私有的构造函数就不能在外界通过new创建实例了(注:有些初学者就会问,有时候我并没有在类中定义构造函数为什么也可以使用new来创建对象,那是因为编译器在背后做了手脚了,当编译器看到我们类中没有定义构造函数,此时编译器会帮我们生成一个公有的无参构造函数)

老鸟:不错,回答的很对,这样你的疑惑就得到解答了啊

菜鸟:那我要在哪里创建类的实例了?

老鸟:你傻啊,当然是在类里面创建了(注:这样定义私有构造函数就是上面的一个思考过程的,要创建实例,自然就要有一个变量来保存该实例把,所以就有了私有变量的声明,但是实现中是定义静态私有变量,朋友们有没有想过——这里为什么定义为静态的呢?对于这个疑问的解释为:每个线程都有自己的线程栈,定义为静态主要是为了在多线程确保类有一个实例)

菜鸟:哦,现在完全明白了,但是我还有另一个疑问——现在类实例创建在类内部,那外界如何获得该的一个实例来使用它了?

老鸟:这个,你可以定义一个公有方法或者属性来把该类的实例公开出去了(注:这样就有了公有方法的定义了,该方法就是提供方法问类的全局访问点)

通过上面的分析,相信大家也就很容易写出单例模式的实现代码了,下面就看看具体的实现代码(看完之后你会惊讶道:真是这样的!):

下面是Singleton.cs的内容:


using System; 
using System.Collections; 
using System.Collections.Generic; 
  
  
public class Singleton : MonoBehaviour 
{ 
  private static GameObject m_Container = null; 
  private static string m_Name = "Singleton"; 
  private static Dictionary<string, object> m_SingletonMap = new Dictionary<string, object>(); 
  private static bool m_IsDestroying = false; 
    
  public static bool IsDestroying 
  { 
    get { return m_IsDestroying; } 
  } 
    
  public static bool IsCreatedInstance(string Name) 
  { 
    if(m_Container == null) 
    { 
      return false; 
    } 
    if (m_SingletonMap!=null && m_SingletonMap.ContainsKey(Name))  
    { 
      return true; 
    } 
    return false; 
      
  } 
  public static object getInstance (string Name) 
  { 
    if(m_Container == null) 
    { 
      Debug.Log("Create Singleton."); 
      m_Container = new GameObject (); 
      m_Container.name = m_Name;   
      m_Container.AddComponent (typeof(Singleton)); 
    } 
    if (!m_SingletonMap.ContainsKey(Name)) { 
      if(System.Type.GetType(Name) != null) 
      { 
        m_SingletonMap.Add(Name, m_Container.AddComponent (System.Type.GetType(Name))); 
      } 
      else 
      { 
        Debug.LogWarning("Singleton Type ERROR! (" + Name + ")"); 
      } 
    } 
    return m_SingletonMap[Name]; 
  }   
    
  public void RemoveInstance(string Name) 
  { 
    if (m_Container != null && m_SingletonMap.ContainsKey(Name)) 
    { 
      UnityEngine.Object.Destroy((UnityEngine.Object)(m_SingletonMap[Name])); 
      m_SingletonMap.Remove(Name); 
        
      Debug.LogWarning("Singleton REMOVE! (" + Name + ")"); 
    } 
  } 
  
  void Awake () 
  { 
    Debug.Log("Awake Singleton."); 
    DontDestroyOnLoad (gameObject); 
  } 
    
  void Start() 
  { 
    Debug.Log("Start Singleton."); 
  }   
    
  void Update() 
  { 
  } 
    
  void OnApplicationQuit() 
  { 
    Debug.Log("Destroy Singleton"); 
    if(m_Container != null) 
    { 
      GameObject.Destroy(m_Container); 
      m_Container = null; 
      m_IsDestroying = true; 
    }       
  } 
    
}