举例讲解C#编程中对设计模式中的单例模式的运用
单例模式的介绍 为什么会有单例模式 剖析单例模式的实现思路 我们从单例模式的概念(确保一个类只有一个实例,并提供一个访问它的全局访问点)入手,可以把概念进行拆分为两部分:(1)确保一个类只有一个实例;(2)提供一个访问它的全局访问点;下面通过采用两人对话的方式来帮助大家更快掌握分析思路: 菜鸟:怎样确保一个类只有一个实例了? 老鸟:那就让我帮你分析下,你创建类的实例会想到用什么方式来创建的呢? 新手:用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; } } } 代码大部分都比较容易看懂,下面介绍几点注意的地方: .NET实现单例模式的类 经过查看,.NET类库中确实存在单例模式的实现类,不过该类不是公开的,下面就具体看看该类的一个实现的(该类具体存在于System.dll程序集,命名空间为System,大家可以用反射工具Reflector去查看源码的): // 该类不是一个公开类 // 但是该类的实现应用了单例模式 internal sealed class SR { private static SR loader; internal SR() { } // 主要是因为该类不是公有,所以这个全部访问点也定义为私有的了 // 但是思想还是用到了单例模式的思想的 private static SR GetLoader() { if (loader == null) { SR sr = new SR(); Interlocked.CompareExchange<SR>(ref loader,sr,null); } return loader; } // 这个公有方法中调用了GetLoader方法的 public static object GetObject(string name) { SR loader = GetLoader(); if (loader == null) { return null; } return loader.resources.GetObject(name,Culture); } } 总结 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |