目录
- 定义
- UML
- 参与者
- 示例
定义:
单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
应用:
每台计算机可以有若干个打印机,但只能有一个Printer Spooler, 以避免两个打印作业同时输出到打印机中。每台计算机可以有若干传真卡,但是只应该有一个软件负责管理传真卡,以避免出现两份传真作业同时传到传真卡中的情况。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。
UML:
参与者:
Singleton 角色:定义一个实例操作,同一段时间只能被一个客户访问。
示例:
代码using System; namespace SingletonPattern { /// <summary> /// Singleton Design Pattern. /// </summary> class MainApp { static void Main() { // Constructor is protected -- cannot use new Singleton s1 = Singleton.Instance(); Singleton s2 = Singleton.Instance(); // Test for same instance if (s1 == s2) { Console.WriteLine("同一个实例"); } Console.ReadKey(); } } class Singleton { private static Singleton _instance; // Constructor is 'protected' protected Singleton() { } public static Singleton Instance() { // Uses lazy initialization. // Note: this is not thread safe. if (_instance == null) { _instance = new Singleton(); } return _instance; } } }
实际运用:
代码// Singleton pattern -- Real World example using System; using System.Collections.Generic; using System.Threading; namespace DoFactory.GangOfFour.Singleton.RealWorld { /// <summary> /// MainApp startup class for Real-World /// Singleton Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main() { LoadBalancer b1 = LoadBalancer.GetLoadBalancer(); LoadBalancer b2 = LoadBalancer.GetLoadBalancer(); LoadBalancer b3 = LoadBalancer.GetLoadBalancer(); LoadBalancer b4 = LoadBalancer.GetLoadBalancer(); // Same instance? if (b1 == b2 && b2 == b3 && b3 == b4) { Console.WriteLine("Same instance\n"); } // Load balance 15 server requests LoadBalancer balancer = LoadBalancer.GetLoadBalancer(); for (int i = 0; i < 15; i++) { string server = balancer.Server; Console.WriteLine("Dispatch Request to: " + server); } // Wait for user Console.ReadKey(); } } /// <summary> /// The 'Singleton' class /// </summary> class LoadBalancer { private static LoadBalancer _instance; private List<string> _servers = new List<string>(); private Random _random = new Random(); // Lock synchronization object private static object syncLock = new object(); // Constructor (protected) protected LoadBalancer() { // List of available servers _servers.Add("ServerI"); _servers.Add("ServerII"); _servers.Add("ServerIII"); _servers.Add("ServerIV"); _servers.Add("ServerV"); } public static LoadBalancer GetLoadBalancer() { // Support multithreaded applications through // 'Double checked locking' pattern which (once // the instance exists) avoids locking each // time the method is invoked if (_instance == null) { lock (syncLock) { if (_instance == null) { _instance = new LoadBalancer(); } } } return _instance; } // Simple, but effective random load balancer public string Server { get { int r = _random.Next(_servers.Count); return _servers[r].ToString(); } } } }