最簡單的設(shè)計(jì)模式學(xué)習(xí):Singleton模式
學(xué)習(xí)設(shè)計(jì)模式,自然從最簡單的模式入手,而最簡單的模式便是Singleton。所以***篇就來所以說Singleton模式??赐闓OF和Design patterns in Java的書,感覺Singleton雖然簡單,但是想寫出一個(gè)好的Singleton也不是一上來就能寫出來的。
Singleton模式的用處自然是保證一個(gè)類只有一個(gè)***的實(shí)例。在建模中涉及到的只能有一個(gè)對象,例如Struts中的Action類就是一例。除此之外,Singleton還使得該對象只有一個(gè)全局訪問點(diǎn)。這就是SIngleton的作用。
說得比較抽象,我們來看一個(gè)簡單Singleton的C++和Java的代碼:
C++ Singleton模式:
類定義:
- class Singleton
 - {
 - public:
 - static Singleton * Instance();
 - ~Singleton();
 - private:
 - Singleton();
 - static Singleton * instance;
 - };
 
方法實(shí)現(xiàn):
- Singleton * Singleton::instance = 0;
 - Singleton::Singleton()
 - {
 - }
 - Singleton::~Singleton()
 - {
 - }
 - Singleton * Singleton::Instance()
 - {
 - if (instance == 0) {
 - instance = new Singleton();
 - }
 - return instance;
 - }
 
Java Singleton模式:
- public class Singleton {
 - private static Singleton instance;
 - public static Singleton getInstance() {
 - if (instance == null)
 - instance = new Singleton();
 - return instance;
 - }
 - /** *//** Creates a new instance of Singleton */
 - private Singleton() {
 - }
 - }
 
通過上面的例子可以看出,Singleton的實(shí)現(xiàn)并不難,只要將構(gòu)造函數(shù)訪問域設(shè)為私有,然后添加一個(gè)靜態(tài)引用和一個(gè)獲得該應(yīng)用的靜態(tài)方法即可。其實(shí)在C++中定義一個(gè)全局靜態(tài)變量也可以達(dá)到這個(gè)效果,但是像Java這樣的語言就是能使用Singleton了。
上面的程序有一個(gè)問題,就是只能運(yùn)行在單線程的環(huán)境下。為此我在C++上作了個(gè)實(shí)驗(yàn)。首先#include 
- Singleton * Singleton::Instance()
 - {
 - if (instance == 0) {
 - Sleep(1000);
 - instance = new Singleton();
 - }
 - return instance;
 - }
 
然后在主函數(shù)中創(chuàng)建兩個(gè)線程,程序如下:
- static Singleton * s1 = 0, * s2 = 0;
 - DWORD WINAPI ThreadProc1(PVOID)
 - {
 - s1 = Singleton::Instance();
 - return 0;
 - }
 - DWORD WINAPI ThreadProc2(PVOID)
 - {
 - s2 = Singleton::Instance();
 - return 0;
 - }
 - int main(int argc, char* argv[])
 - {
 - DWORD threadID1;
 - DWORD threadID2;
 - CreateThread(NULL, 0, ThreadProc1, NULL, 0, &threadID1);
 - CreateThread(NULL, 0, ThreadProc2, NULL, 0, &threadID2);
 - Sleep(10000);
 - std::cout << s1 << " " << s2;
 - return 0;
 - }
 
這樣修改后在運(yùn)行程序,打印出來的s1和s2地址就不是同一個(gè)地址了。結(jié)果如下:
0372D68 00372E68Press any key to continue
可見當(dāng)在多線程環(huán)境下使用這個(gè)Singleton就會(huì)出現(xiàn)創(chuàng)建不止一個(gè)實(shí)力的情況,所以我們需要給Singleton加鎖。請看下面的代碼。
C++ Singleton模式:
- class Singleton
 - {
 - public:
 - static Singleton * Instance();
 - virtual ~Singleton();
 - private:
 - Singleton();
 - static CMutex mutex;
 - static Singleton * instance;
 - };
 
- Singleton * Singleton::instance = 0;
 - CMutex Singleton::mutex;
 - Singleton::Singleton()
 - {
 - }
 - Singleton::~Singleton()
 - {
 - }
 - Singleton * Singleton::Instance()
 - {
 - mutex.Lock();
 - if (instance == 0) {
 - Sleep(1000);
 - instance = new Singleton();
 - }
 - mutex.Unlock();
 - return instance;
 - }
 
此外需要#include < afxmt.h>,
Java Singleton模式:
- public class Singleton {
 - private static Singleton instance;
 - private static Object lock = Singleton.class;
 - public static Singleton getInstance() {
 - synchronized (lock) {
 - if (instance == null)
 - instance = new Singleton();
 - return instance;
 - }
 - }
 - /** *//** Creates a new instance of Singleton */
 - private Singleton() {
 - }
 - }
 
運(yùn)用加鎖就可以解決在多線程環(huán)境下使用Singleton模式所帶來的問題了。
【編輯推薦】















 
 
 





 
 
 
 