第3章 單例模式_第1頁
第3章 單例模式_第2頁
第3章 單例模式_第3頁
第3章 單例模式_第4頁
第3章 單例模式_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、常文萃常文萃*一個多文檔一個多文檔MDI應(yīng)用程序應(yīng)用程序*只生成一個對象只生成一個對象*新的問題及改進(jìn)方案新的問題及改進(jìn)方案*單例單例模式模式*C+實現(xiàn)單例實現(xiàn)單例*靜態(tài)初始化靜態(tài)初始化一、問題描述一、問題描述 寫一個寫一個MDI(Multiple Document Interface)窗體程序,包含)窗體程序,包含兩個窗體,其中一個是兩個窗體,其中一個是“工具箱工具箱”窗體,單擊菜單命令時生成一窗體,單擊菜單命令時生成一個工具箱。個工具箱。二、初步實現(xiàn)二、初步實現(xiàn)1.新建項目新建項目選擇選擇“Windows窗體應(yīng)用程窗體應(yīng)用程序序”;2.輸輸入項目名稱入項目名稱選擇存儲位置選擇存儲位置確定;

2、確定;3.設(shè)設(shè)置窗體的置窗體的IsMdiContainer屬性為屬性為true,或者或者雙擊窗體后寫如雙擊窗體后寫如下代碼:下代碼:private void Form1_Load(object sender, EventArgs e) this.IsMdiContainer = true; 4.在窗體上建在窗體上建立一個菜單立一個菜單ToolStripMenuItem ToolBox作為啟動作為啟動工具箱的按工具箱的按鈕:雙擊鈕:雙擊“工具箱工具箱”面板上的面板上的“菜單和工具欄菜單和工具欄”中的中的“MenuStrip”,生成一個菜單項,生成一個菜單項,單單擊擊 選擇選擇“MenuItem”

3、,在,在屬性窗口修改其屬性窗口修改其Text屬性為屬性為“工具箱工具箱”;5.“項目項目”菜單中菜單中“添加添加Windows窗體窗體”,輸入名稱,輸入名稱“FormToolbox.cs”添加;添加;6.設(shè)設(shè)置新置新窗體的窗體的FormBorderStyle屬性為屬性為“FixedToolWindow”,“Size”屬性為屬性為123(寬),(寬),290(高);(高);7.在新窗在新窗體設(shè)體設(shè)計窗口中,雙擊計窗口中,雙擊“工工具具箱箱”面板上面板上“公公共共控件控件”中的中的“Button”,生成一個按鈕,然后復(fù)制出來兩個按鈕,生成一個按鈕,然后復(fù)制出來兩個按鈕,分別設(shè)置他們的分別設(shè)置他們的

4、Text屬性為:工屬性為:工具一、工具二、工具具一、工具二、工具三;三;8.在在“解決方案資源管理器解決方案資源管理器”中雙擊中雙擊“Form1.cs”打開打開Form1窗窗體,雙體,雙擊菜擊菜單單欄的圖標(biāo)打欄的圖標(biāo)打開代碼窗口開代碼窗口。光標(biāo)定位在下列事件中:光標(biāo)定位在下列事件中:private void toolStripMenuItem1_Click(object sender, EventArgs e) 9.在函數(shù)體中在函數(shù)體中輸入以下代碼輸入以下代碼: FormToolbox ftb = new FormToolbox(); ftb.MdiParent = this; ftb.Sho

5、w();10. 運行程序。單擊工具箱可以彈出工具箱窗體。多次單擊,多運行程序。單擊工具箱可以彈出工具箱窗體。多次單擊,多次彈出。次彈出。三、三、只生成一個對象只生成一個對象為了使工具箱只出現(xiàn)一次,可以在單擊事件中判斷這個工具箱窗體是為了使工具箱只出現(xiàn)一次,可以在單擊事件中判斷這個工具箱窗體是不是出現(xiàn)過。因此,對不是出現(xiàn)過。因此,對ftb的定義應(yīng)該放在事件之前。同時修改代碼的定義應(yīng)該放在事件之前。同時修改代碼如下:如下:private FormToolbox ftb;private void toolStripMenuItem1_Click(object sender, EventArgs e)

6、 if (ftb = null) ftb = new FormToolbox(); ftb.MdiParent = this; ftb.Show(); 四、增加工具按鈕,運行時單擊工具按鈕也可以實例化工具箱窗體。四、增加工具按鈕,運行時單擊工具按鈕也可以實例化工具箱窗體。1.右擊右擊“解決方案資源管理器解決方案資源管理器”中的中的“Form1.cs”,選,選“打開打開”;2.在工具箱中雙擊在工具箱中雙擊“菜單和工具欄菜單和工具欄”中的中的“ToolStrip”,在生成的圖標(biāo)在生成的圖標(biāo)處單擊選處單擊選”Button”;3. 再雙擊該圖標(biāo)進(jìn)入代碼窗口,寫如下代碼:再雙擊該圖標(biāo)進(jìn)入代碼窗口,寫如下

7、代碼: private void toolStripButton1_Click(object sender, EventArgs e) if (ftb = null) ftb = new FormToolbox(); ftb.MdiParent = this; ftb.Show(); 4. 運行程運行程序序分析存在問題:分析存在問題:(1)運行時,若關(guān)閉了工具箱窗體就再也彈不出來,)運行時,若關(guān)閉了工具箱窗體就再也彈不出來, 原因是關(guān)閉了原因是關(guān)閉了的窗口資源已釋放,但并不為的窗口資源已釋放,但并不為null,其其IsDisposed屬性為屬性為true。(2)代碼重復(fù),若要五個地方都需要實例

8、化代碼重復(fù),若要五個地方都需要實例化“工具箱工具箱”窗體得重復(fù)窗體得重復(fù)五次相同的代碼,且若有小五次相同的代碼,且若有小bug,需要改變五個地方,需要改變五個地方。五、封裝實例化工具箱的代碼為一個方法五、封裝實例化工具箱的代碼為一個方法 private void openToolbox() if (ftb = null | ftb.IsDisposed) ftb = new FormToolbox(); ftb.MdiParent = this; ftb.Show(); 相關(guān)相關(guān)代碼改進(jìn)為:代碼改進(jìn)為: private FormToolbox ftb; private void toolStr

9、ipMenuItem1_Click(object sender, EventArgs e) openToolbox(); private void toolStripButton1_Click(object sender, EventArgs e) openToolbox(); private void openToolbox() if (ftb = null|ftb.IsDisposed) ftb = new FormToolbox(); ftb.MdiParent = this; ftb.Show(); 五五、由工具箱窗體自己決定是否生成實例、由工具箱窗體自己決定是否生成實例 在在Form

10、1.cs中判斷是否彈出工具箱窗體不合適,應(yīng)該由工具箱窗體自己決中判斷是否彈出工具箱窗體不合適,應(yīng)該由工具箱窗體自己決定。為此,需要在定。為此,需要在FormToolbox.cs中將構(gòu)造函數(shù)改為中將構(gòu)造函數(shù)改為私有私有,不允許外部程序,不允許外部程序?qū)嵗嵗?具體做法是:右擊具體做法是:右擊FormToolbox.cs,選選擇擇“查查看代看代碼碼”,修改如下:,修改如下: private static FormToolbox ftb = null; /新增加的代碼新增加的代碼 private FormToolbox( ) /被修改的構(gòu)造函數(shù)被修改的構(gòu)造函數(shù) InitializeCom

11、ponent(); public FormToolbox ( ) /新增加的代新增加的代碼碼,注意注意 if (ftb = null | ftb.IsDisposed) ftb = new FormToolbox( ); ftb.MdiParent = Form1.ActiveForm ; return ftb; 同時,應(yīng)該修改掉同時,應(yīng)該修改掉原來寫在原來寫在Form1.cs中的相應(yīng)代中的相應(yīng)代碼如下:碼如下: private void toolStripMenuItem1_Click(object sender, EventArgs e) FormToolbox .GetInstance(

12、 ).Show( ); private void toolStripButton1_Click(object sender, EventArgs e) FormToolbox .GetInstance( ).Show( ); 并去掉原來的并去掉原來的openToolbox( )方法。方法。六六、單例模式、單例模式單例模式單例模式(Singleton)保證一個類僅有一個實例,并提供保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。一個訪問它的全局訪問點。單單例模式的例模式的要要點點:1. 1. 某某個類只能有一個實例個類只能有一個實例;2. 2. 它它必須自行創(chuàng)建這個實例必須自行創(chuàng)建這個實例

13、;3. 3. 它它必須自行向整個系統(tǒng)提供這個實例必須自行向整個系統(tǒng)提供這個實例。單單例模式是一種對象創(chuàng)建型模式。單例模式又名例模式是一種對象創(chuàng)建型模式。單例模式又名單件模式單件模式或或單單態(tài)模式態(tài)模式。建建立一個控制臺應(yīng)用程序,編寫如下類代碼:立一個控制臺應(yīng)用程序,編寫如下類代碼: class Singleton private static Singleton instance; private Singleton( ) / public static Singleton GetInstance( ) if (instance = null) instance = new Singleton

14、( ); return instance; 客戶端代碼如下:客戶端代碼如下: static void Main(string args) Singleton s1 = Singleton.GetInstance( ); Singleton s2 = Singleton.GetInstance( ); if (s1 = s2) Console.WriteLine(兩個對象是相同的實例兩個對象是相同的實例.); Console.Read(); 運行程序,分析結(jié)果。運行程序,分析結(jié)果。C+代碼:代碼:#includeusing namespace std;class Singleton privat

15、e: static Singleton *instance; Singleton() cout+endl; public: static Singleton * GetInstance( ) if(instance=NULL) instance =new Singleton(); return instance; ;Singleton * Singleton:instance =NULL;int main( ) Singleton *s1=Singleton:GetInstance(); Singleton *s2=Singleton:GetInstance(); if(s1=s2) cout

16、兩個實例相同兩個實例相同!endl; return 0;七、靜態(tài)初始化七、靜態(tài)初始化進(jìn)進(jìn)程程:正在運行中的程序稱為進(jìn)程。:正在運行中的程序稱為進(jìn)程。線程線程:一個進(jìn)程可以分成若干個獨立的執(zhí)行流,稱為線程。線程是操:一個進(jìn)程可以分成若干個獨立的執(zhí)行流,稱為線程。線程是操作系統(tǒng)向其分配處理時間的基本單位,可以獨立占用處理器的時間片,作系統(tǒng)向其分配處理時間的基本單位,可以獨立占用處理器的時間片,同一進(jìn)程中的線程可以共享該進(jìn)程的資源的內(nèi)存空間。每一個進(jìn)程至同一進(jìn)程中的線程可以共享該進(jìn)程的資源的內(nèi)存空間。每一個進(jìn)程至少包含一個線程。少包含一個線程。靜靜態(tài)初始化態(tài)初始化方法可解決多線程環(huán)境下避免生成多個實

17、例的問題。方法可解決多線程環(huán)境下避免生成多個實例的問題。public sealed class Singleton private static readonly Singleton instance = new Singleton( ); private Singleton( ) public static Singleton GetInstance() return instance; 客客戶端程序不變,測試代碼。戶端程序不變,測試代碼。八、單例模式的優(yōu)八、單例模式的優(yōu)缺缺點點1.1.優(yōu)點優(yōu)點提提供了對唯一實例的受控訪問供了對唯一實例的受控訪問。因為單例類封裝了它的唯一實例,。因為單例類封

18、裝了它的唯一實例,所以它可以嚴(yán)格控制客戶怎樣以及何時訪問它,并為設(shè)計及開發(fā)團(tuán)所以它可以嚴(yán)格控制客戶怎樣以及何時訪問它,并為設(shè)計及開發(fā)團(tuán)隊提供了共享的概念。隊提供了共享的概念。由于在系統(tǒng)內(nèi)存中只存在一個對象,因此由于在系統(tǒng)內(nèi)存中只存在一個對象,因此可以節(jié)約系統(tǒng)資源可以節(jié)約系統(tǒng)資源,對于,對于一些需要頻繁創(chuàng)建和銷毀的對象,單例模式無疑可以提高系統(tǒng)的性一些需要頻繁創(chuàng)建和銷毀的對象,單例模式無疑可以提高系統(tǒng)的性能。能。允許可變數(shù)目的實例允許可變數(shù)目的實例。我們可以基于單例模式進(jìn)行擴(kuò)展,使用與單。我們可以基于單例模式進(jìn)行擴(kuò)展,使用與單例控制相似的方法來獲得指定個數(shù)的對象實例。例控制相似的方法來獲得指定個數(shù)的對象實例。2 2. .缺缺點點由于單例模式中沒有抽象層,因此由于單例模式中沒有抽象層,因此單例類的擴(kuò)展有很大的困單例類的擴(kuò)展有很大的困難難。單例類的職責(zé)過重單例類的職責(zé)過重,在一定程度上違背了,在一定程度上違背了“單一職責(zé)原則單一職責(zé)原則”。因為單例類既充當(dāng)了工廠角色,提供了工廠方法,同時又充當(dāng)因為單例類既充當(dāng)了工廠角色,提供了工廠方法,同時又充當(dāng)了產(chǎn)品角色,包含一些業(yè)務(wù)方法,將產(chǎn)品的創(chuàng)建和產(chǎn)品的本身了產(chǎn)品角色,包含一些業(yè)務(wù)方法,將產(chǎn)品的創(chuàng)建和產(chǎn)品的本身的功能融合到一起。的功能融合到一起。濫用單例將帶來一些負(fù)面問題濫用單例將帶來一些負(fù)面問題,如為了節(jié)省資源將

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論