An implementation of the singleton pattern must:
- ensure that only one instance of the singleton class ever exists
- class creates its own singleton pattern instance
- provide global access to that instance.
Typically, this is done by:
- declaring all constructors of the class to be private
- providing a static method that returns a reference to the instance.
Java
//Lazy loading(not recommend)
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
//Non-lazy loading(recommend)
public final class Singleton {
// create instance
private static final Singleton INSTANCE = new Singleton();
// set constructor as null, so that no instance will be created
private Singleton() {}
// return this singletion instance
public static Singleton getInstance() {
return INSTANCE;
}
}
//enum(recommend)
public enum Singleton {
INSTANCE;
public void dummy() {
}
}
// how to use
SingletonEnum singleton = SingletonEnum.INSTANCE;
singleton.dummy();
Python
// Lazy loading
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instance
class MyClass(Singleton):
a = 1
//meta class
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class MyClass(metaclass=Singleton):
pass
//decorator
from functools import wraps
def singleton(cls):
instances = {}
@wraps(cls)
def getinstance(*args, **kw):
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance
@singleton
class MyClass(object):
a = 1
C++
#include <iostream>
class Singleton
{
private:
/* Here will be the instance stored. */
static Singleton* instance;
/* Private constructor to prevent instancing. */
Singleton();
public:
/* Static access method. */
static Singleton* getInstance();
};
/* Null, because instance will be initialized on demand. */
Singleton* Singleton::instance = 0;
Singleton* Singleton::getInstance()
{
if (instance == 0)
{
instance = new Singleton();
}
return instance;
}
Singleton::Singleton()
{}
int main()
{
//new Singleton(); // Won't work
Singleton* s = Singleton::getInstance(); // Ok
Singleton* r = Singleton::getInstance();
/* The addresses will be the same. */
std::cout << s << std::endl;
std::cout << r << std::endl;
}