設(shè)計(jì)模式之單件模式(Singleton Pattern )
2024-07-21 02:16:29
供稿:網(wǎng)友
 
單件模式
singleton pattern 
 
singleton 模式,它包含在創(chuàng)造性模式系列中。
創(chuàng)造性模式指示如何以及何時創(chuàng)建對象。singleton 模式可以保證一個類有且只有一個實(shí)例,并提供一個訪問它的全局訪問點(diǎn)。在程序設(shè)計(jì)過程中,有很多情況需要確保一個類只能有一個實(shí)例。例如,系統(tǒng)中只能有一個窗口管理器、一個打印假脫機(jī),或者一個數(shù)據(jù)引擎的訪問點(diǎn)。pc機(jī)中可能有幾個串口,但只能有一個com1實(shí)例。
其結(jié)構(gòu)如下:
我們可以定義一個spooler類,實(shí)現(xiàn)singleton 模式
 
public class spooler
 private shared spool_counter as integer
 private shared glbspooler as spooler
 private legalinstance as boolean
 '-----
 private sub new()
 mybase.new()
 if spool_counter = 0 then '建立并且保存這個實(shí)例
glbspooler = me '保存實(shí)例
spool_counter = spool_counter + 1 '計(jì)數(shù)
 legalinstance = true
 else
 legalinstance = false
 throw new spoolerexception
 end if
 end sub
 '-----
 public shared function getspooler() as spooler
 try
 glbspooler = new spooler()
 catch e as exception
throw e '實(shí)例已經(jīng)存在
 finally
 getspooler = glbspooler '返回唯一的實(shí)例 
 end try
 end function
 '-----
 public sub print(byval str as string)
 if legalinstance then
 messagebox.show(str)
 else
 throw new spoolerexception()
 end if
 end sub
 '-----
end class
 
 
 
 
spoolerexception類
 
public class spoolerexception
 inherits exception
 private mesg as string
 '--------- 
 public sub new()
 mybase.new()
 mesg = "只能創(chuàng)建一個實(shí)例!"
 end sub
 '---------
 public overrides readonly property message() as string
 get
 message = mesg
 end get 
 end property 
end class
 
使用單件模式
 
private spl as spooler
private sub errorbox(byval mesg as string)
 messagebox.show(mesg, "spooler error", messageboxbuttons.ok)
end sub
private sub btgetspooler_click (byval sender as system.object, byval e as system.eventargs) handles btgetspooler.click
 try
 spl = spooler.getspooler
 textbox1.text = "創(chuàng)建實(shí)例!"
 catch ex as exception
 errorbox("實(shí)例已經(jīng)創(chuàng)建,并且只能創(chuàng)建一個實(shí)例!")
 end try
 end sub
 
private sub print_click (byval sender as system.object, byval e as system.eventargs) handles print.click
 try
 spl.print("實(shí)例已經(jīng)創(chuàng)建,并且你單擊了按鈕!")
 catch ex as exception
 errorbox("沒有創(chuàng)建實(shí)例,不能執(zhí)行!")
 end try
end sub
 
運(yùn)行
 
如圖:
 
當(dāng)點(diǎn)擊”創(chuàng)建實(shí)例”按鈕時,調(diào)用spooler 類的getspooler方法,試圖創(chuàng)建實(shí)例。在spooler的構(gòu)造函數(shù)中,定義了spool_counter 變量,這個變量用于計(jì)算spooler實(shí)例的數(shù)量,如果為0(即還未創(chuàng)建spooler實(shí)例),則創(chuàng)建一個spooler實(shí)例并保存。然后增加計(jì)數(shù)器的值,如果再次點(diǎn)擊”創(chuàng)建實(shí)例”按鈕,因?yàn)閟pooler實(shí)例的數(shù)量為1,則拋出異常,這樣就可以控制并創(chuàng)建唯一的實(shí)例。
構(gòu)造函數(shù)如下:
private sub new()
 mybase.new()
 if spool_counter = 0 then '建立并且保存這個實(shí)例
glbspooler = me '保存實(shí)例
spool_counter = spool_counter + 1 '計(jì)數(shù)
 legalinstance = true
 else
 legalinstance = false
 throw new spoolerexception
 end if
 end sub
可以通過修改構(gòu)造函數(shù)中對spool_counter的判斷條件來控制創(chuàng)建spooler實(shí)例的任意個數(shù)。這可以說是單件模式的擴(kuò)充吧!:)
 
private sub new()
 mybase.new()
 if spool_counter <= 3 then '建立并且保存這個實(shí)例
glbspooler = me '保存實(shí)例
 spool_counter = spool_counter + 1 '計(jì)數(shù)
 legalinstance = true
 else
 legalinstance = false
 throw new spoolerexception
 end if
 end sub