單例模式

出自ProgWiki
跳至導覽 跳至搜尋

單例模式(Singleton),確保一個類別只有一個實體,並提供對該實體的全域存取。

應用

C++

  • C++需要自己在程式結束前自己做destroy() 不然會造成 Memory Leak,可配合AutoPtr.h使用。
template <typename T>
class Singleton {
public:
    static T *instance();
    static void destroy();
private:
    Singleton();
    ~Singleton();
private:
    static T *_instance;
};
 
template <typename T>
T *Singleton<T>::_instance = NULL;
 
template <typename T>
T *Singleton<T>::instance() {
    if (_instance == NULL) {
        _instance = new T;
    }
 
    return _instance;
}
 
template <typename T>
void Singleton<T>::destroy() {
    if (_instance != NULL)
        delete _instance;
}
 
template <typename T>
Singleton<T>::Singleton() {
}
 
template <typename T>
Singleton<T>::~Singleton() {
}
 
class TestClass {
public:
    TestClass(){}
    ~TestClass(){}
    const char *TestProc() {
        return "Hello World";
    }
};
 
// Somewhere in the code
.....
   AutoPtr<TestClass> pTestClass(Singleton<TestClass>::instance());
   cout << pTestClass->TestProc();

C#

/// Parent for singleton
/// <typeparam name="T">Singleton class</typeparam>
  public class Singleton<T> where T : class, new()
  {
    protected Singleton() { }
    private sealed class SingletonCreator<S> where S : class, new()
    {
      private static readonly S instance = new S();
      //explicit static constructor to disable beforefieldinit      
      static SingletonCreator() { }
      public static S CreatorInstance
      {
        get { return instance; }
      }
    }
    public static T Instance
    {
      get { return SingletonCreator<T>.CreatorInstance; }
    }
  }
/// Concrete Singleton
public class TestClass : Singleton<TestClass>
{
    public string TestProc()
    {
        return "Hello World";
    }
}
// Somewhere in the code
.....
TestClass.Instance.TestProc();
.....

Java

public final class TestClass {
    // volatile is needed so that multiple thread can reconcile the instance
    private volatile static TestClass _instance;
 
    private TestClass(){}
 
    public static TestClass getInstance() { // synchronized keyword has been removed from here
        if (_instance == null) { // needed because once there is singleton available no need to aquire monitor again & again as it is costly
            synchronized(TestClass.class) {
                if (_instance == null) { // this is needed if two threads are waiting at the monitor at the time when singleton was getting instantiated
                   _instance = new TestClass();
                }
            }
        }
        return _instance;
      }
 
 
     //.....
     public string TestProc()
     {
        return "Hello World";
     }
}
 
// Somewhere in the code
.....
TestClass.getInstance().TestProc();
.....