解读设计模式----单例模式(Singleton Pattern)
??? ? 單例模式可以保證一個(gè)類有且只有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn).在程序設(shè)計(jì)中,有很多情況需要確保一個(gè)類只能有一個(gè)實(shí)例.從這句話可以看出,Singleton模式的核心:如何控制用戶使用new對一個(gè)類的實(shí)例構(gòu)造器的任意調(diào)用。如何繞過常規(guī)的構(gòu)造器,提供一種機(jī)制來保證一個(gè)類只有一個(gè)實(shí)例?這應(yīng)該是類設(shè)計(jì)者的責(zé)任,而不是使用者的責(zé)任。
?一、單例模式意圖
????? 保證一個(gè)類有且只有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
二、單例模式UML圖(該圖來至http://www.dofactory.com/)
?????
三、示例解說單例模式
????? 看看下面這個(gè)簡單的示例:
?2{
?3????public?class?Singleton
?4????{
?5????????//靜態(tài)私有屬性
?6????????private?static?Singleton?instance;
?7
?8????????///?<summary>
?9????????///?私有構(gòu)造器--讓類的使用者調(diào)用不到此構(gòu)造器
10????????///?</summary>
11????????private?Singleton()
12????????{?}
13
14????????public?static?Singleton?Instance
15????????{
16????????????get?
17????????????{
18????????????????if?(instance?==?null)
19????????????????{
20????????????????????instance?=?new?Singleton();
21????????????????}
22????????????????return?instance;??//返回的總是第一次實(shí)例的對象
23????????????}
24????????}
25????}
26
27????//測試類
28????class?TestSingleton
29????{
30????????public?static?void?Main2(string[]?args)
31????????{
32????????????Singleton?t1?=?Singleton.Instance;
33????????????Singleton?t2?=?Singleton.Instance;
34????????????Console.WriteLine(object.ReferenceEquals(t1,?t2)?==?true);
35????????}
36????}
37}
???? 提供一個(gè)靜態(tài)的私有屬性,并提供get來實(shí)現(xiàn)一個(gè)簡單的單例.此外我們還可以通過靜態(tài)只讀屬性來實(shí)現(xiàn).看看下面這個(gè)MSDN上提供的示例:
?1/**////?<summary>?2///?MSDN上Singleton模式的實(shí)現(xiàn)
?3///?</summary>
?4public?class?MsdnSingleton
?5{
?6???//聲明的同時(shí)進(jìn)行初始化
?7???public?static?readonly?MsdnSingleton?Instance?=?new?MsdnSingleton();
?8????????
?9???/**////?<summary>
10???///?私有構(gòu)造器
11???///?</summary>
12???private?MsdnSingleton()
13???{
14???}
15}
????? 這樣的單例實(shí)現(xiàn)的實(shí)質(zhì)等同于提供一個(gè)靜態(tài)的屬性字段,通過靜態(tài)構(gòu)造器來初始化這個(gè)屬性.因?yàn)?font face="Verdana">要想訪問靜態(tài)字段,那靜態(tài)構(gòu)造器就首先執(zhí)行,下面是代碼示例:
?1public?class?SameSingleton?2{
?3???//要想訪問靜態(tài)字段,那靜態(tài)構(gòu)造器就首先執(zhí)行
?4???public?static?readonly?SameSingleton?Instance;
?5????????
?6???/**////?<summary>
?7???///?靜態(tài)構(gòu)造器-初始化Instance
?8???///?靜態(tài)構(gòu)造器-完成靜態(tài)字段(Instance)的初始化
?9???///?</summary>
10??static?SameSingleton()
11??{
12??????Instance?=?new?SameSingleton();
13??}
14
15??/**////?<summary>
16??///?私有構(gòu)造器
17??///?</summary
18??private?SameSingleton()
19??{
20?
21??}
22}
????? 上面的實(shí)現(xiàn)完全可以達(dá)到單例模式的意圖,保證一個(gè)類僅且有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn).而這在實(shí)際應(yīng)用我們還得注意一點(diǎn),就是在多線程的調(diào)用.于此,我們還得保證線程安全.要保證線程安全其實(shí)也是很簡單就可以實(shí)現(xiàn)的,只需要通過加鎖和雙重判斷就OK,下面是簡單的多線程的線程安全的實(shí)現(xiàn):
?1using?System;?2using?System.Collections.Generic;
?3using?System.Text;
?4
?5//多線程的Singleton模式實(shí)現(xiàn)
?6namespace?DesignPattern.Singleton
?7{
?8????public?class?SingletonMultithread
?9????{
10????????private?static?object?lockHelper?=?new?object();
11
12????????private?static?volatile?SingletonMultithread?instane?=?null;
13????????public?static?SingletonMultithread?Instane
14????????{
15????????????get?
16????????????{
17????????????????if?(instane?==?null)??//雙檢查
18????????????????{
19????????????????????lock?(lockHelper)
20????????????????????{
21????????????????????????if?(instane?==?null)
22????????????????????????{
23????????????????????????????instane?=?new?SingletonMultithread();
24????????????????????????}
25????????????????????}
26????????????????}
27????????????????return?instane;
28????????????}
29????????}
30????????
31
32????????//私有構(gòu)造方法
33????????private?SingletonMultithread()?
34????????{
35
36????????}
37????}
38
39????class?TestSingletonMultithread
40????{
41????????public?static?void?Main()
42????????{
43????????????SingletonMultithread?s1?=?SingletonMultithread.Instane;
44????????????SingletonMultithread?s2?=?SingletonMultithread.Instane;
45????????????Console.WriteLine(object.ReferenceEquals(s1,?s2)?==?true);
46????????}
47????}
48}
49
其中:private static volatile Singleton instance=null;
--volatile:保證特定平臺的實(shí)現(xiàn)必須不要去從新調(diào)整指令,保證對象構(gòu)造的一個(gè)非常嚴(yán)格的順序。
四、真實(shí)項(xiàng)目中的單例
????? 我曾經(jīng)做過一個(gè)網(wǎng)球場的管理系統(tǒng),客戶要求使用C/S,(隨便PS下客戶,在我做需求的時(shí)候建議客戶做B/S系統(tǒng),管理和部署就很方便,也不用帶上幾百M(fèi)的.NET Frameworks去裝在客戶電腦上了。可好心討不了客戶的笑顏,他硬說我是在給他做網(wǎng)頁,還說他要的是軟件不是網(wǎng)頁,汗過........),在使用C/S做程序的時(shí)候我想大家都遇到過這樣的情況,無論是通過按扭點(diǎn)擊還是菜單來導(dǎo)航,通常我們是像下面這樣實(shí)現(xiàn)的:
2{
3????ratForm?rat?=?new?ratForm();
4????rat.MdiParent?=?this;
5????rat.Show();
6
7}
???? 我這里是使用的菜單控件,通過點(diǎn)擊打開新窗體。如果是這樣問題就出現(xiàn)了,每當(dāng)我們點(diǎn)擊一次菜單上的菜單項(xiàng)就會啟動一個(gè)窗體,點(diǎn)幾次就會啟動幾個(gè)窗體。見下圖:
????? 這樣顯然是不符合要求的,我們應(yīng)該做到讓每個(gè)窗體只能Show一個(gè)出來,這時(shí) 單例模式 就能派上用場了。要保證外部不能創(chuàng)建類的實(shí)例,才單例中就是通過設(shè)置構(gòu)造方法為私有private,所謂模式可說是一種設(shè)計(jì)套路,這里我們就依葫蘆畫瓢來畫一次單例,設(shè)置構(gòu)造方法私有,代碼如下;
2{
3????InitializeComponent();
4}
????? 通過一個(gè)靜態(tài)方法來對完成靜態(tài)屬性的初始化;
?1private?static?ratForm?ratf?=?null;?2public?static?ratForm?GetInstance()
?3{
?4???if?(ratf?==?null?||?ratf.IsDisposed)
?5???{
?6??????ratf?=?new?ratForm();
?7??????ratf.MdiParent?=?mainForm.ActiveForm;
?8???}
?9???return?ratf;
10}
???? 通過單例模式的引入,私有了構(gòu)造方法,并通過一個(gè)靜態(tài)的方法初始化靜態(tài)字段,保證了類的唯一實(shí)例,方法GetInstance()就是單例的全局訪問點(diǎn)。這樣設(shè)計(jì)后就通過GetInstance()方法就得了這個(gè)窗體的唯一實(shí)例。
1private?void?ratingToolStripMenuItem_Click(object?sender,?EventArgs?e)2{
3????//ratForm?rat?=?new?ratForm();
4????//rat.MdiParent?=?this;
5????//rat.Show();
6????ratForm.GetInstance().Show();
7}
???? 通過單例模式的引入,改善了程序的設(shè)計(jì),在窗體調(diào)用處只需要通過全局訪問點(diǎn)這個(gè)靜態(tài)方法就可以得到唯一的實(shí)例對象,然后調(diào)用其Show()方法,就達(dá)到了我們的要求。
五、使用單線程Singleton模式要點(diǎn)
--Singleton模式中的實(shí)例構(gòu)造器可以設(shè)置為protected以也許子類派生。
--Singleton模式一般不要支持ICloneable接口,因?yàn)檫@可能導(dǎo)致對個(gè)對象實(shí)例,與Singleton的意圖違背。
--Singleton模式一般不要支持序列化,因?yàn)檫@也有可能導(dǎo)致多個(gè)對象實(shí)例,同樣與Singleton模式的意圖違背。
--Singleton模式只考慮到了對象創(chuàng)建的管理,沒有考慮對銷毀的管理。對于自帶垃圾回收的平臺可不考慮這點(diǎn)。
上面總結(jié)源于MSDN WebCast
---------------------------------------------------------------------------------------------------------
轉(zhuǎn)載于:https://www.cnblogs.com/beniao/archive/2008/05/13/1145918.html
總結(jié)
以上是生活随笔為你收集整理的解读设计模式----单例模式(Singleton Pattern)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JDBC操作数据库就这八步!
- 下一篇: Asp.Net MVC1.0正式版发布