网站导航
:
网学
原创论文
原创专题
网站设计
最新系统
原创论文
论文降重
发表论文
论文发表
UI设计定制
论文答辩PPT格式排版
期刊发表
论文专题
最新论文
推荐专题
热门论文
论文专题
网站首页
论文模板
设计资源
程序设计
编程文档
营销学习
设计下载
参考使用
网学资源
网络学习
学习知识
交易代码
关于网学
安全工程
自动化
保险
表演
财务管理
参考选题
论文选题-查重参考论文
参考论文大全
电气工程及其自动化
电子论文
电子信息工程
电子商务
法律
法学
工程管理
公共关系学
公共事业管理
公路工程
公路交通运输
工商管理
广告学
国际经济与贸易
汉语国际教育
汉语言文学
环境科学与工程
化学
会计学
护理学
交通运输
教育管理
教育研究生
经济学
金融
计算机科学与技术
计算机应用
酒店管理
机械电子工程
机械论文
机械设计制造及其自动化
论文查重
旅游管理
python开发
生物工程
环境工程
数字媒体技术
ios开发
工程造价
家庭教育
农学
家政学
原创检测通过
期刊发表方法
当前位置:
网学
>
设计资源
>
.Net编程
> 正文
单件模式(SingletonPattern)
论文降重修改服务、格式排版等
获取论文
论文降重及排版
论文发表
相关服务
概述
Singleton
模式要求一个类有且仅有一个实例,并且提供了一个全局的访问点。这就提出了一个问题:如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?客户程序在调用某一个类时,它是不会考虑这个类是否只能有一个实例等问题的,所以,这应该是类设计者的责任,而不是类使用者的责任。
从另一个角度来说,
Singleton
模式其实也是一种职责型模式。因为我们创建了一个对象,这个对象扮演了独一无二的角色,在这个单独的对象实例中,它集中了它所属类的所有权力,同时它也肩负了行使这种权力的职责!
意图
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
模型图
逻辑模型图:
物理模型图:
生活中的例子
美国总统的职位是Singleton,美国宪法规定了总统的选举,任期以及继任的顺序。这样,在任何时刻只能由一个现任的总统。无论现任总统的身份为何,其头衔"美利坚合众国总统"是访问这个职位的人的一个全局的访问点。
五种实现
1
.简单实现
1
public
sealed
class
Singleton
2
{
3
static
Singleton instance
=
null
;
4
5
Singleton()
6
{
7
}
8
9
public
static
Singleton Instance
10
{
11
get
12
{
13
if
(instance
==
null
)
14
{
15
instance
=
new
Singleton();
16
}
17
return
instance;
18
}
19
}
20
}
这种方式的实现对于线程来说并不是安全的,因为在多线程的环境下有可能得到Singleton类的多个实例。如果同时有两个线程去判断(instance == null),并且得到的结果为真,这时两个线程都会创建类Singleton的实例,这样就违背了Singleton模式的原则。实际上在上述代码中,有可能在计算出表达式的值之前,对象实例已经被创建,但是内存模型并不能保证对象实例在第二个线程创建之前被发现。
该实现方式主要有两个优点:
l
由于实例是在
Instance
属性方法内部创建的,因此类可以使用附加功能(例如,对子类进行实例化),即使它可能引入不想要的依赖性。
l
直到对象要求产生一个实例才执行实例化;这种方法称为“惰性实例化”。惰性实例化避免了在应用程序启动时实例化不必要的
singleton
。
2
.安全的线程
1
public
sealed
class
Singleton
2
{
3
static
Singleton instance
=
null
;
4
static
readonly
object
padlock
=
new
object
();
5
6
Singleton()
7
{
8
}
9
10
public
static
Singleton Instance
11
{
12
get
13
{
14
lock
(padlock)
15
{
16
if
(instance
==
null
)
17
{
18
instance
=
new
Singleton();
19
}
20
return
instance;
21
}
22
}
23
}
24
}
25
26
这种方式的实现对于线程来说是安全的。我们首先创建了一个进程辅助对象,线程在进入时先对辅助对象加锁然后再检测对象是否被创建,这样可以确保只有一个实例被创建,因为在同一个时刻加了锁的那部分程序只有一个线程可以进入。这种情况下,对象实例由最先进入的那个线程创建,后来的线程在进入时(
instence == null
)为假,不会再去创建对象实例了。但是这种实现方式增加了额外的开销,损失了性能。
3
.双重锁定
这种实现方式对多线程来说是安全的,同时线程不是每次都加锁,只有判断对象实例没有被创建时它才加锁,有了我们上面第一部分的里面的分析,我们知道,加锁后还得再进行对象是否已被创建的判断。它
解决了线程并发问题,同时避免在每个
Instance
属性方法的调用中都出现独占锁定。它还允许您将实例化延迟到第一次访问对象时发生。实际上,应用程序很少需要这种类型的实现。大多数情况下我们会用静态初始化。
这种方式仍然有很多缺点:无法实现延迟初始化。
1
public
sealed
class
Singleton
2
{
3
static
Singleton instance
=
null
;
4
static
readonly
object
padlock
=
new
object
();
5
6
Singleton()
7
{
8
}
9
10
public
static
Singleton Instance
11
{
12
get
13
{
14
if
(instance
==
null
)
15
{
16
lock
(padlock)
17
{
18
if
(instance
==
null
)
19
{
20
instance
=
new
Singleton();
21
}
22
}
23
}
24
return
instance;
25
}
26
}
27
}
28
4
.静态初始化
看到上面这段富有戏剧性的代码,我们可能会产生怀疑,这还是
Singleton
模式吗?
在此实现中,将在第一次引用类的任何成员时创建实例。公共语言运行库负责处理变量初始化。该类标记为
sealed
以阻止发生派生,而派生可能会增加实例。此外,变量标记为
readonly
,这意味着只能在静态初始化期间(此处显示的示例)或在类构造函数中分配变量。
1
public
sealed
class
Singleton
2
{
3
static
readonly
Singleton instance
=
new
Singleton();
4
5
static
Singleton()
6
{
7
}
8
9
Singleton()
10
{
11
}
12
13
public
static
Singleton Instance
14
{
15
get
16
{
17
return
instance;
18
}
19
}
20
}
21
该实现与前面的示例类似,不同之处在于它依赖公共语言运行库来初始化变量。它仍然可以用来解决
Singleton
模式试图解决的两个基本问题:全局访问和实例化控制。公共静态属性为访问实例提供了一个全局访问点。此外,由于构造函数是私有的,因此不能在类本身以外实例化
Singleton
类;因此,变量引用的是可以在系统中存在的唯一的实例。
由于
Singleton
实例被私有静态成员变量引用,因此在类首次被对
Instance
属性的调用所引用之前,不会发生实例化。
这种方法唯一的潜在缺点是,您对实例化机制的控制权较少。在
Design Patterns
形式中,您能够在实例化之前使用非默认的构造函数或执行其他任务。由于在此解决方案中由
.NET Framework
负责执行初始化,因此您没有这些选项。在大多数情况下,静态初始化是在
.NET
中实现
Singleton
的首选方法。
5
.延迟初始化
这里,初始化工作有
Nested类的一个静态成员来完成,这样就实现了延迟初始化,并具有很多的优势,是值得推荐的一种实
现方式。
1
public
sealed
class
Singleton
2
{
3
Singleton()
4
{
5
}
6
7
public
static
Singleton Instance
8
{
9
get
10
{
11
return
Nested.instance;
12
}
13
}
14
15
class
Nested
16
{
17
static
Nested()
18
{
19
}
20
21
internal
static
readonly
Singleton instance
=
new
Singleton();
22
}
23
}
24
实现要点
l
Singleton模式是限制而不是改进类的创建。
l
Singleton类中的实例构造器可以设置为Protected以允许子类派生。
l
Singleton模式一般不要支持Icloneable接口,因为这可能导致多个对象实例,与Singleton模式的初衷违背。
l
Singleton模式一般不要支持序列化,这也有可能导致多个对象实例,这也与Singleton模式的初衷违背。
l
Singleton只考虑了对象创建的管理,没有考虑到销毁的管理,就支持垃圾回收的平台和对象的开销来讲,我们一般没必要对其销毁进行特殊的管理。
l
理解和扩展Singleton模式的核心是“如何控制用户使用new对一个类的构造器的任意调用”。
l
可以很简单的修改一个
Singleton
,使它有少数几个实例,这样做是允许的而且是有意义的
。
优点
l
实例控制:
Singleton
会阻止其他对象实例化其自己的
Singleton
对象的副本,从而确保所有对象都访问唯一实例
l
灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程
缺点
l
开销:虽然数量很少,
但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题,上面的五种实现方式中已经说过了。
l
可能的开发混淆:
使用
singleton
对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用
new
关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
l
对象的生存期:
Singleton
不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于 .NET Framework 的语言),只有
Singleton
类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除
对象实例,但这样会导致
Singleton
类中出现悬浮引用。
适用性
l
当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
l
当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
应用场景
l
每台计算机可以有若干个打印机,但只能有一个
Printer Spooler
,避免两个打印作业同时输出到打印机。
(摘自吕震宇的
C#
设计模式(7
)-Singleton Pattern
)
l
PC
机中可能有几个串口,但只能有一个
COM1
口的实例。
l
系统中只能有一个窗口管理器。
l
.NET Remoting
中服务器激活对象中的
Sigleton
对象,确保所有的客户程序的请求都只有一个实例来处理。
完整示例
这是一个简单的计数器例子,四个线程同时进行计数。
1
using
System;
2
using
System.Threading;
3
4
namespace
SigletonPattern.SigletonCounter
5
{
6
///
<summary>
7
///
功能:简单计数器的单件模式
8
///
编写:Terrylee
9
///
日期:2005年12月06日
10
///
</summary>
11
public
class
CountSigleton
12
{
13
///
存储唯一的实例
14
static
CountSigleton uniCounter
=
new
CountSigleton();
15
16
///
存储计数值
17
private
int
totNum
=
0
;
18
19
private
CountSigleton()
20
21
{
22
///
线程延迟2000毫秒
23
Thread.Sleep(
2000
);
24
}
25
26
static
public
CountSigleton Instance()
27
28
{
29
30
return
uniCounter;
31
32
}
33
34
///
计数加1
35
public
void
Add()
36
{
37
totNum
++
;
38
}
39
40
///
获得当前计数值
41
public
int
GetCounter()
42
{
43
return
totNum;
44
}
45
46
}
47
}
48
1
using
System;
2
using
System.Threading;
3
using
System.Text;
4
5
namespace
SigletonPattern.SigletonCounter
6
{
7
///
<summary>
8
///
功能:创建一个多线程计数的类
9
///
编写:Terrylee
10
///
日期:2005年12月06日
11
///
</summary>
12
public
class
CountMutilThread
13
{
14
public
CountMutilThread()
15
{
16
17
}
18
19
///
<summary>
20
///
线程工作
21
///
</summary>
22
public
static
void
DoSomeWork()
23
{
24
///
构造显示字符串
25
string
results
=
""
;
26
27
///
创建一个Sigleton实例
28
CountSigleton MyCounter
=
CountSigleton.Instance();
29
30
///
循环调用四次
31
for
(
int
i
=
1
;i
<
5
;i
++
)
32
{
33
///
开始计数
34
MyCounter.Add();
35
36
results
+=
"
线程
"
;
37
results
+=
Thread.CurrentThread.Name.ToString()
+
"
——〉
"
;
38
results
+=
"
当前的计数:
"
;
39
results
+=
MyCounter.GetCounter().ToString();
40
results
+=
"
\n
"
;
41
42
Console.WriteLine(results);
43
44
///
清空显示字符串
45
results
=
""
;
46
}
47
}
48
49
public
void
StartMain()
50
{
51
52
Thread thread0
=
Thread.CurrentThread;
53
54
thread0.Name
=
"
Thread 0
"
;
55
56
Thread thread1
=
new
Thread(
new
ThreadStart(DoSomeWork));
57
58
thread1.Name
=
"
Thread 1
"
;
59
60
Thread thread2
=
new
Thread(
new
ThreadStart(DoSomeWork));
61
62
thread2.Name
=
"
Thread 2
"
;
63
64
Thread thread3
=
new
Thread(
new
ThreadStart(DoSomeWork));
65
66
thread3.Name
=
"
Thread 3
"
;
67
68
thread1.Start();
69
70
thread2.Start();
71
72
thread3.Start();
73
74
///
线程0也只执行和其他线程相同的工作
75
DoSomeWork();
76
}
77
}
78
}
79
1
using
System;
2
using
System.Text;
3
using
System.Threading;
4
5
namespace
SigletonPattern.SigletonCounter
6
{
7
///
<summary>
8
///
功能:实现多线程计数器的客户端
9
///
编写:Terrylee
10
///
日期:2005年12月06日
11
///
</summary>
12
public
class
CountClient
13
{
14
public
static
void
Main(
string
[] args)
15
{
16
CountMutilThread cmt
=
new
CountMutilThread();
17
18
cmt.StartMain();
19
20
Console.ReadLine();
21
}
22
}
23
}
24
总结
Singleton
设计模式是一个非常有用的机制,可用于在面向对象的应用程序中提供单个访问点。文中通过五种实现方式的比较和一个完整的示例,完成了对
Singleton
模式的一个总结和探索。用一句广告词来概括
Singleton
模式就是“简约而不简单”。
_________________________________________________________________________________________________
上一篇资讯:
ASP.NET设计中的性能优化问题
下一篇资讯:
7条大型网站设计和维护的关键技巧
相关资讯
相关文章
7条大型网站设计和维护的关键技巧
ASP.NET经典60道面试题
总结一下网站注入与防范的方法
SQLTrim函數
SQLSUBSTRING函數
相关专题
WinForm窗体之间交互的一些方法
VS中创建自定义SQLRule
三种方法在Infopath中实现数据有效性验证
如何使用和开发自定义配置节
C#获得当前文件夹内所有文件的名称,大小,类型,属
网学推荐
·
原创论文的写法
·
论文数据图表制作
·
论文排版通过检测检测
·
提供系统开发和运行服务
·
提供原创参考资料
·
档案托管服务
·
原创参考论文导航
·
查重服务维普检测低于30%
·
我们提供原创参考论文和原创的参
·
原创的论文资料参考节省时间!
·
论文格式排版 格式核对!
·
UI设计定制、界面设计
·
程序和网站等UI设计定制!
·
原创参考论文参考定制!
·
职称和论文发表,可联系业务我们
·
本科毕业设计(论文)答辩指南
·
程序制作专家
原创论文
·
财务管理
·
参考选题
·
论文选题-查重参考论文
·
参考论文大全
·
电气工程及其自动化
·
电子论文
·
电子信息工程
·
电子商务
·
工程管理
·
公共关系学
·
公共事业管理
·
公路工程
·
公路交通运输
·
工商管理
·
广告学
·
家政学
文章排行榜
·
自然框架的源代码、Demo、数据库、
·
WebService身份验证
·
不要迷失在技术的海洋中
·
.net完美操作cookies
·
取出文本中的图片地址
·
谷歌眼中的搜索未来
·
GridView显示隐藏某一列
·
谈谈关于MVP模式中V-P交互问题【附
·
ASP.NET网站预编译概述
·
详解.net内存管理
·
json教程之C#开发json解析类
·
用FCKEditor编辑器上传图片、FLASH
·
C#调用WebService时的身份验证
·
WinForm窗体之间交互的一些方法
·
VS中创建自定义SQLRule
·
三种方法在Infopath中实现数据有效
·
如何使用和开发自定义配置节
·
C#获得当前文件夹内所有文件的名称
设为首页
|
加入收藏
|
网学首页
|
原创论文
|
计算机原创
版权所有 网学网 [
Myeducs.cn
] 您电脑的分辨率是
像素
Copyright 2008-2020
myeducs.Cn
www.myeducs.Cn
All Rights Reserved
湘ICP备09003080号
常年法律顾问:王律师