目录
- 定义
- 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();
}
}
}
}