模式分析
在某种程度上,单例模式中限制而不是改进类的创建,单例模式可以保证一个类有且只有一个实例.
并提供一个访问的全局访问点.在程序设计过程中,有很多情况需要保证一个类只有一个实例.
特点:
~ 单例类只能有一个实例
~ 单例类必须自己创建自己的唯一实例.
~ 单例类必须给所有其他对象提供这一实例.
在哪些情况下使用单例模式
使用单例模式有一个必要条件:在一个系统要求一个类只有一个实例时才应当使用单例模式.
反过来,如果一个类可以有几个实例共存,就不要使用单例模式.
不要使用单例模式存取全局变量,这违背了单例模式的用意,最好放到对应类Static成员中.
不要将数据库连接做成单例,因为一个系统可能会与数据库有多个连接,并且在有连接池的
情况下,应当尽可能及时释放连接.Singleton模式由于使用静态成员存储类实例,所以可能会造成
资源无法及时释放,带来问题.
源码分析
控制台程序 Program.cs
![](/Images/OutliningIndicators/ContractedBlock.gif)
Singleton_8023
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Threading;
5
using System.Collections;
6![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//*该源码由邹江平2008-8-14编写,如有学习者请与QQ:200580231联系*/
7
namespace X8023Z
8![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
9
class LoadBalancer
10![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
11
private static LoadBalancer Balancer;
12
private ArrayList ArrayList_Server = new ArrayList();
13
private Random random = new Random();
14![](/Images/OutliningIndicators/InBlock.gif)
15
protected LoadBalancer()
16![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
17
ArrayList_Server.Add("服务器I");
18
ArrayList_Server.Add("服务器II");
19
ArrayList_Server.Add("服务器III");
20
ArrayList_Server.Add("服务器IV");
21
ArrayList_Server.Add("服务器V");
22
}
23![](/Images/OutliningIndicators/InBlock.gif)
24
public static LoadBalancer GetLoadBalancer()
25![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
26
if (Balancer == null)
27![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
28
Mutex mutex = new Mutex();
29
mutex.WaitOne();
30
if (Balancer == null)
31
Balancer = new LoadBalancer();
32
mutex.Close();
33
}
34
return Balancer;
35
}
36
public string Server
37![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
38
get
39![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
40
int r = random.Next(ArrayList_Server.Count);
41
return ArrayList_Server[r].ToString();
42
}
43
}
44
}
45![](/Images/OutliningIndicators/InBlock.gif)
46![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//**/
47![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
48
/// SingletonApp test
49
/// </summary>
50
///
51
public class SingletonApp
52![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
53
public static void Main(string[] args)
54![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
55
LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
56
LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
57
LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
58
LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
59![](/Images/OutliningIndicators/InBlock.gif)
60
// Same instance?
61
if ((b1 == b2) && (b2 == b3) && (b3 == b4))
62
Console.WriteLine("同步运行相同的实例对象");
63
64
// Do the load balancing
65
Console.WriteLine(b1.Server);
66
Console.WriteLine(b2.Server);
67
Console.WriteLine(b3.Server);
68
Console.WriteLine(b4.Server);
69
Console.WriteLine("请按任意键退出 !");
70
Console.Read();
71
}
72
}
73
}/*该源码由邹江平2008-8-14编写,如有学习者请与QQ:200580231联系*/
![](/Emoticons/msn/bat.gif)
功能说明:该代码显示了负载均衡实例对象,在负载均衡模型中,有多台服务器可提供服务
任务分配器随机挑选一台服务器提供服务,以确保任务均衡(实际情况比这个
复杂得多).这里,任务分配实例只有一个,负责挑选服务器并分配任务.
![](/Emoticons/msn/bat.gif)
补充说明:
.NET Framework平台优势实现Singleton 实例.
sealed class Singleton
{
private extern Singleton();
public static readonly Singleton Instance=new Singelton();
}
这样代码虽然很少,但解决了线程的性能上的损失,工作原理是:Singleton类被声明为Sealed,
用于不会被继承,将成员变量Instance声明为Public readonly ,并在声明时被初始化,通过这些
改变,确实得到了Singleton的设计模式
但这存在一定的根本问题,实例在程序运行时就被初始化.无法实现延迟初始化,为解决这
一问题,实现了延迟初始化.
样例如下:
public sealed class Singleton
{
Singleton()
{}
public static Singleton GetInstance()
{
return Nested.instance;
}
class Nested
{
static Nested()
{}
internal static readonly Singleton instance=new Singleton();
}
}