




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第詳解Go語(yǔ)言設(shè)計(jì)模式之單例模式目錄單例模式的概念單例模式結(jié)構(gòu)單例模式的使用場(chǎng)景單例模式例子:特殊的計(jì)數(shù)器第一個(gè)單元測(cè)試單例模式實(shí)現(xiàn)單例模式優(yōu)缺點(diǎn)
單例模式的概念
單例模式很容易記住。就像名稱一樣,它只能提供對(duì)象的單一實(shí)例,保證一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問該實(shí)例的方法。
在第一次調(diào)用該實(shí)例時(shí)被創(chuàng)建,然后在應(yīng)用程序中需要使用該特定行為的所有部分之間重復(fù)使用。
單例模式結(jié)構(gòu)
單例模式的使用場(chǎng)景
你會(huì)在許多不同的情況下使用單例模式。比如:
當(dāng)你想使用同一個(gè)數(shù)據(jù)庫(kù)連接來(lái)進(jìn)行每次查詢時(shí)當(dāng)你打開一個(gè)安全Shell(SSH)連接到一個(gè)服務(wù)器來(lái)做一些任務(wù)時(shí)。而不想為每個(gè)任務(wù)重新打開連接如果你需要限制對(duì)某些變量或空間的訪問,你可以使用一個(gè)單例作為作為這個(gè)變量的門(在Go中使用通道可以很好地實(shí)現(xiàn))如果你需要限制對(duì)某些空間的調(diào)用數(shù)量,你可以創(chuàng)建一個(gè)單例實(shí)例使得這種調(diào)用只在可接受的窗口中進(jìn)行
單例模式還有跟多的用途,這里只是簡(jiǎn)單的舉出一些。
單例模式例子:特殊的計(jì)數(shù)器
我們可以寫一個(gè)計(jì)數(shù)器,它的功能是用于保存它在程序執(zhí)行期間被調(diào)用的次數(shù)。這個(gè)計(jì)數(shù)器的需要滿足的幾個(gè)要求:
當(dāng)之前沒有創(chuàng)建過(guò)計(jì)數(shù)器count時(shí),將創(chuàng)建一個(gè)新的計(jì)數(shù)器count=0如果已經(jīng)創(chuàng)建了一個(gè)計(jì)數(shù)器,則返回此實(shí)例實(shí)際保存的count數(shù)如果我們調(diào)用方法AddOne一次,計(jì)數(shù)count必須增加1
在這個(gè)場(chǎng)景下,我們需要有3個(gè)測(cè)試來(lái)堅(jiān)持我們的單元測(cè)試。
第一個(gè)單元測(cè)試
與Java或C++這種面向?qū)ο笳Z(yǔ)言中不同,Go實(shí)現(xiàn)單例模式?jīng)]有像靜態(tài)成員的東西(通過(guò)static修飾),但是可以通過(guò)包的范圍來(lái)提供一個(gè)類似的功能。
首先,我們要為單例對(duì)象編寫包的聲明:
packagesingleton
typeSingletonstruct{
countint
varinstance*Singleton
funcinit(){
instance=Singleton{}
funcGetInstance()*Singleton{
returnnil
func(s*Singleton)AddOne()int{
return0
然后,我們通過(guò)編寫測(cè)試代碼來(lái)驗(yàn)證我們聲明的函數(shù):
packagesingleton
import(
"testing"
funcTestGetInstance(t*testing.T){
count:=GetInstance()
ifcount==nil{
t.Error("Anewconnectionobjectmusthavebeenmade")
expectedCounter:=count
currentCount:=count.AddOne()
ifcurrentCount!=1{
t.Errorf("Aftercallingforthefirsttimetocount,thecountmustbe1butitis%d\n",currentCount)
count2:=GetInstance()
ifcount2!=expectedCounter{
t.Error("Singletoninstancesmustbedifferent")
currentCount=count2.AddOne()
ifcurrentCount!=2{
t.Errorf("Aftercalling'AddOne'usingthesecondcounter,thecurrentcountmustbe2butwas%d\n",currentCount)
}
第一個(gè)測(cè)試是檢查是顯而易見,但在復(fù)雜的應(yīng)用中,其重要性也不小。當(dāng)我們要求獲得一個(gè)計(jì)數(shù)器的實(shí)例時(shí),我們實(shí)際上需要得到一個(gè)結(jié)果。
我們把對(duì)象的創(chuàng)建委托給一個(gè)未知的包,而這個(gè)對(duì)象在創(chuàng)建或檢索對(duì)象時(shí)可能失敗。我們還將當(dāng)前的計(jì)數(shù)器存儲(chǔ)在變量expectedCounter中,以便以后進(jìn)行比較。即:
currentCount:=count.AddOne()
ifcurrentCount!=1{
t.Errorf("Aftercallingforthefirsttimetocount,thecountmustbe1butitis%d\n",currentCount)
}
運(yùn)行上面的代碼:
$gotest-v-run=GetInstance.
===RUNTestGetInstance
singleton_test.go:12:Anewconnectionobjectmusthavebeenmade
singleton_test.go:19:Aftercallingforthefirsttimetocount,thecountmustbe1butitis0
singleton_test.go:31:Aftercalling'AddOne'usingthesecondcounter,thecurrentcountmustbe2butwas0
---FAIL:TestGetInstance(0.00s)
FAIL/yuzhoustayhungry/GoDesignPattern/singleton0.412s
單例模式實(shí)現(xiàn)
最后,我們必須實(shí)現(xiàn)單例模式。正如我們前面提到的,通常做法是寫一個(gè)靜態(tài)方法和實(shí)例來(lái)檢索單例模式實(shí)例。
在Go中,沒有static這個(gè)關(guān)鍵字,但是我們可以通過(guò)使用包的范圍來(lái)達(dá)到同樣的效果。
首先,我們創(chuàng)建一個(gè)結(jié)構(gòu)體,其中包含我們想要保證的對(duì)象在程序執(zhí)行過(guò)程中成為單例的對(duì)象。
packagesingleton
typeSingletonstruct{
countint
varinstance*Singleton
funcinit(){
instance=Singleton{}
funcGetInstance()*Singleton{
ifinstance==nil{
instance=new(Singleton)
returninstance
func(s*Singleton)AddOne()int{
s.count++
returns.count
}
我們來(lái)分析一下這段代碼的差別,在Java或C++語(yǔ)言中,變量實(shí)例會(huì)在程序開始時(shí)被初始化為NULL。但在Go中,你可以將結(jié)構(gòu)的指針初始化為nil,但不能將一個(gè)結(jié)構(gòu)初始化為nil(相當(dāng)于其他語(yǔ)言的NULL)。
所以varinstance*singleton*這一語(yǔ)句定義了一個(gè)指向結(jié)構(gòu)的指針為nil,而變量稱為instance。
我們創(chuàng)建了一個(gè)GetInstance方法,檢查實(shí)例是否已經(jīng)被初始化(instance==nil),并在已經(jīng)分配的空間中創(chuàng)建一個(gè)實(shí)例instance=new(singleton)。
Addone()方法將獲取變量實(shí)例的計(jì)數(shù),并逐個(gè)加1,然后返回當(dāng)前計(jì)數(shù)器的值。
再一次運(yùn)行單元測(cè)試代碼:
$gotest-v-run=GetInstance.
===RUNTestGetInstance
---PASS:TestGetInstance(0.00s)
ok/yuzhoustayhungry/GoDesignPattern/singleton0.297s
單例模式優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
你可以保證一個(gè)類只有一個(gè)實(shí)例。你獲得了一個(gè)指向該實(shí)例的全局訪問節(jié)點(diǎn)。僅在首次請(qǐng)求單例對(duì)象時(shí)對(duì)其進(jìn)行初始化。
缺點(diǎn):
違反了單一職責(zé)原則。該模式同時(shí)解決了兩個(gè)問題。單例模式可能掩蓋不良設(shè)計(jì),比如程序各組件之間相互了解過(guò)多等。該模式在多線程環(huán)境下需要進(jìn)行特殊
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 品牌營(yíng)銷及推廣專項(xiàng)協(xié)議
- 成都設(shè)計(jì)咨詢集團(tuán)有限公司2025年社會(huì)公開招聘(19人)筆試參考題庫(kù)附帶答案詳解
- 2025重慶新華出版集團(tuán)招聘編輯風(fēng)控審計(jì)等崗位12人筆試參考題庫(kù)附帶答案詳解
- 2025廣西機(jī)場(chǎng)管理集團(tuán)有限責(zé)任公司第一批次招聘136人筆試參考題庫(kù)附帶答案詳解
- 2025年棗莊市重點(diǎn)產(chǎn)業(yè)鏈急需緊缺人才需求(900人)筆試參考題庫(kù)附帶答案詳解
- 《化學(xué)工業(yè)與生活》課件
- 調(diào)試技師面試題及答案
- 激活傳統(tǒng)文化新生機(jī)的創(chuàng)新策略與行動(dòng)方案
- 綠化補(bǔ)充合同協(xié)議書
- 養(yǎng)殖污水處理合同協(xié)議書
- 客戶生命周期價(jià)值預(yù)測(cè)-第1篇-深度研究
- 文化轉(zhuǎn)型時(shí)代的文化基因與共生教育選擇
- 《田徑理論知識(shí)》課件
- 專題05-必修三-必過(guò)知識(shí)點(diǎn)清單(解析版)(新教材北師大版)
- 2025年四川航空股份有限公司招聘筆試參考題庫(kù)含答案解析
- 鐵路機(jī)車車輛制動(dòng)鉗工(高級(jí))職業(yè)鑒定考試題庫(kù)(含答案)
- 河北省保定市重點(diǎn)中學(xué)2025屆高考英語(yǔ)一模試卷含解析
- 《便攜式揮發(fā)性有機(jī)物檢測(cè)儀 (PID)技術(shù)要求及監(jiān)測(cè)規(guī)范》
- 甲亢碘131治療的護(hù)理
- 中建群塔作業(yè)防碰撞專項(xiàng)施工方案
- 2025屆江蘇省南京師范大學(xué)附屬中學(xué)高考仿真卷英語(yǔ)試題含解析
評(píng)論
0/150
提交評(píng)論