最簡單的設計模式學習:Singleton模式
學習設計模式,自然從最簡單的模式入手,而最簡單的模式便是Singleton。所以***篇就來所以說Singleton模式??赐闓OF和Design patterns in Java的書,感覺Singleton雖然簡單,但是想寫出一個好的Singleton也不是一上來就能寫出來的。
Singleton模式的用處自然是保證一個類只有一個***的實例。在建模中涉及到的只能有一個對象,例如Struts中的Action類就是一例。除此之外,Singleton還使得該對象只有一個全局訪問點。這就是SIngleton的作用。
說得比較抽象,我們來看一個簡單Singleton的C++和Java的代碼:
C++ Singleton模式:
類定義:
- class Singleton
 - {
 - public:
 - static Singleton * Instance();
 - ~Singleton();
 - private:
 - Singleton();
 - static Singleton * instance;
 - };
 
方法實現(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的實現(xiàn)并不難,只要將構造函數(shù)訪問域設為私有,然后添加一個靜態(tài)引用和一個獲得該應用的靜態(tài)方法即可。其實在C++中定義一個全局靜態(tài)變量也可以達到這個效果,但是像Java這樣的語言就是能使用Singleton了。
上面的程序有一個問題,就是只能運行在單線程的環(huán)境下。為此我在C++上作了個實驗。首先#include 
- Singleton * Singleton::Instance()
 - {
 - if (instance == 0) {
 - Sleep(1000);
 - instance = new Singleton();
 - }
 - return instance;
 - }
 
然后在主函數(shù)中創(chuàng)建兩個線程,程序如下:
- 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;
 - }
 
這樣修改后在運行程序,打印出來的s1和s2地址就不是同一個地址了。結果如下:
0372D68 00372E68Press any key to continue
可見當在多線程環(huán)境下使用這個Singleton就會出現(xiàn)創(chuàng)建不止一個實力的情況,所以我們需要給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() {
 - }
 - }
 
運用加鎖就可以解決在多線程環(huán)境下使用Singleton模式所帶來的問題了。
【編輯推薦】















 
 
 





 
 
 
 