設計模式(C ) 01單例模式

2021-09-03 07:47:40 字數 3363 閱讀 8555

推薦閱讀:

為什麼要學習設計模式呢?我以前也思考過很多次這個問題,現在也還困惑。為什麼我最後還是選擇了學設計模式呢?因為在遊戲中,用到的次數太多了,真的有必要學習了,所以我打算來好好研究一下。

今天開始,我將與大家一起來學習設計模式,博主是做遊戲的,所以我採用c#語言來與大家分享設計模式,話不多說,我們直接進入正題。

單例模式是我遇到的第乙個設計模式,也是最常用到的設計模式,幾乎沒個遊戲都會用到單例。

所謂單例,就是乙個類只有乙個例項。

單例模式:確保乙個類只有乙個例項,並提供乙個全域性訪問點。

下面這個類圖可以幫助大家更形象的理解。

下面舉個兩個例子來幫助大家理解單例模式的應用

1.遊戲中的使用:遊戲中玩家的屬性,不使用單利模式可能會出現玩家死亡增加血量的情況。為此,我們引入單例,使得同一時間只允許乙個例項對其操作。

2.現實中的例子:印表機,乙個裝置如果同時列印兩個檔案,會出現兩個檔案內容交錯現象。

現在我們已經大致了解了單例模式的應用場景,那麼,在遊戲中我們如何實現呢?

從單例模式中我們可以總結兩個要點:

(1)確保乙個類只有乙個例項;

(2)提供乙個訪問它的全域性訪問點;

下面通過採用兩人對話的方式來幫助大家更快掌握分析思路:

菜鳥:怎樣確保乙個類只有乙個例項了?

老鳥:那就讓我幫你分析下,你建立類的例項會想到用什麼方式來建立的》呢?

新手:用new關鍵字啊,只要new下就建立了該類的乙個例項了,之後就》可以使用該類的一些屬性和例項方法了

老鳥:那你想過為什麼可以使用new關鍵字來建立類的例項嗎?

菜鳥:這個還有條件的嗎?…, 哦,我想起來了,如果類定義私有的建構函式就不能在外界通過new建立例項了(注:有些初學者就會問,有時候我並沒有在類中定義建構函式為什麼也可以使用new來建立物件,那是因為編譯器在背後做了手腳了,當編譯器看到我們類中沒有定義建構函式,此時編譯器會幫我們生成乙個公有的無參建構函式)

老鳥:不錯,回答的很對,這樣你的疑惑就得到解答了啊

菜鳥:那我要在**建立類的例項了?

老鳥:你傻啊,當然是在類裡面建立了(注:這樣定義私有建構函式就是上面的乙個思考過程的,要建立例項,自然就要有乙個變數來儲存該例項把,所以就有了私有變數的宣告,但是實現中是定義靜態私有變數,朋友們有沒有想過——這裡為什麼定義為靜態的呢?對於這個疑問的解釋為:每個執行緒都有自己的執行緒棧,定義為靜態主要是為了在多執行緒確保類有乙個例項)

菜鳥:哦,現在完全明白了,但是我還有另乙個疑問——現在類例項建立在類內部,那外界如何獲得該的乙個例項來使用它了?

老鳥:這個,你可以定義乙個公有方法或者屬性來把該類的例項公開出去了(注:這樣就有了公有方法的定義了,該方法就是提供方法問類的全域性訪問點)

菜鳥:怎樣確保乙個類只有乙個例項了?

老鳥:那就讓我幫你分析下,你建立類的例項會想到用什麼方式來建立的呢?

新手:用new關鍵字啊,只要new下就建立了該類的乙個例項了,之後就可以使用該類的一些屬性和例項方法了

老鳥:那你想過為什麼可以使用new關鍵字來建立類的例項嗎?

菜鳥:這個還有條件的嗎?…, 哦,我想起來了,如果類定義私有的建構函式就不能在外界通過new建立例項了(注:有些初學者就會問,有時候我並沒有在類中定義建構函式為什麼也可以使用new來建立物件,那是因為編譯器在背後做了手腳了,當編譯器看到我們類中沒有定義建構函式,此時編譯器會幫我們生成乙個公有的無參建構函式)

老鳥:不錯,回答的很對,這樣你的疑惑就得到解答了啊

菜鳥:那我要在**建立類的例項了?

老鳥:你傻啊,當然是在類裡面建立了(注:這樣定義私有建構函式就是上面的乙個思考過程的,要建立例項,自然就要有乙個變數來儲存該例項把,所以就有了私有變數的宣告,但是實現中是定義靜態私有變數,朋友們有沒有想過——這裡為什麼定義為靜態的呢?對於這個疑問的解釋為:每個執行緒都有自己的執行緒棧,定義為靜態主要是為了在多執行緒確保類有乙個例項)

菜鳥:哦,現在完全明白了,但是我還有另乙個疑問——現在類例項建立在類內部,那外界如何獲得該的乙個例項來使用它了?

老鳥:這個,你可以定義乙個公有方法或者屬性來把該類的例項公開出去了(注:這樣就有了公有方法的定義了,該方法就是提供方法問類的全域性訪問點)

在遊戲中,就像在電影裡,應該只有乙個導演(遊戲管理人)。遊戲管理人是乙個類,這個類在遊戲中指揮發生的事情。它控制物件的呈現。它控制位置更新。它將玩家的輸入指向正確的遊戲角色。

引擎應該阻止建立乙個以上的遊戲管理人類的例項,通過單例設計模式來實現。此設計模式確保為給定類例項化有且只有乙個物件。

下面我們來看看**怎麼實現吧:

/// /// 單例模式的實現

///

public class gamemanager

/// /// 定義公有方法提供乙個全域性訪問點,同時你也可以定義公有屬性來提供全域性訪問點

///

///

public static gamemanager instance()

return _instance;}}

注意:上述方法在單執行緒情況下堪稱完美,但是在多執行緒的情況下會得到多個gamemanager例項,因為在兩個執行緒同時執行gamemanager方法時,此時兩個執行緒判斷(_instance==null)這個條件時都返回真,此時兩個執行緒就都會建立gamemanager的例項。那麼,這時候你可能會想到:使gamemanager方法在同一時間只執行乙個執行緒執行。

/// /// 單例模式的實現

///

public class gamemanager

/// /// 定義公有方法提供乙個全域性訪問點,同時你也可以定義公有屬性來提供全域性訪問點

///

///

public static gamemanager getinstance()

}return _instance;}}

/// /// 單例模式的實現

///

public class gamemanager

/// /// 定義公有方法提供乙個全域性訪問點,同時你也可以定義公有屬性來提供全域性訪問點

///

///

public static gamemanager getinstance()}}

return _instance;}}

看了上面的**你或許有疑問:為什麼前面判斷了_instance== null,後面又判斷了,你或許會覺得沒必要,但是,這個是很重要的,因為這時候我們考慮的是多執行緒,前一時刻判斷了不代表下一時刻還是該狀態。

01 設計模式 單例模式

package com.hxh public class hungry public static hungry getinstance public static void main string args start 注意事項 變數hungry必須是 私有,靜態,不可變 構造器私有 公開的get...

01 設計模式 單例模式

package com.hxh public class hungry public static hungry getinstance public static void main string args start 注意事項 變數hungry必須是 私有,靜態,不可變 構造器私有 公開的get...

設計模式 01單例設計模式

所謂類的單例設計模式,就是採取一定的方法保證在整個軟體系統中,對某個類只能存在乙個物件例項,並且該類只提供乙個取得其物件例項的方法 靜態方法 比如hibernate中的sessionfactory,它充當的就是資料儲存源的 並負責建立session物件。sessionfactory並不是輕量級的,一...