设计模式

2022-12-21  本文已影响0人  咚咚董dyh

单例模式

一个类仅有一个实例,并提供一个全局访问点,该实例被所有程序模块共享。

Java基于ClassLoader机制确保类只被实例化1次。多线程安全,没有加锁,类加载时初始化,浪费内存。

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
        return instance;  
    }  
}

Java基于枚举类的常量确保类只被实例化1次(实际上枚举常量在内部都转化为枚举类的实例)。多线程安全,支持序列化机制,非Lazy初始化。

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}

Python利用类地址和类变量的全局唯一性确保类只被实例化1次(实例变量不是全局唯一的)。

Python类(class)通过__new__()创造实例(instance),继承并修改__new__()方法,检验类变量。

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kw):  # 类实例化时的传参可以接收到,默认参数接收不到
        if cls._instance is None:
            cls._instance = object.__new__(cls)
        return cls._instance
    def __init__(self):
        pass

single1 = Singleton()
single2 = Singleton()
print(id(single1) == id(single2))

使用Python函数装饰器,检验类变量。

def singleton(cls):
    _instance = {}

    def func():
        if cls not in _instance:
            _instance[cls] = cls()
        return _instance[cls]
    return func
    
@singleton
class Cls(object):
    def __init__(self):
        pass

cls1 = Cls()
cls2 = Cls()
print(id(cls1) == id(cls2))

使用Python函数装饰器,检验类变量。

class Singleton(object):
    def __init__(self, cls):
        self._cls = cls
        self._instance = {}
    def __call__(self):
        if self._cls not in self._instance:
            self._instance[self._cls] = self._cls()
        return self._instance[self._cls]

@Singleton
class Cls2(object):
    def __init__(self):
        pass

cls1 = Cls2()
cls2 = Cls2()
print(id(cls1) == id(cls2))

C++中static对象的初始化

non-local static对象(函数外)。初始化发生在main函数执行之前,也即main函数之前的单线程启动阶段,所以不存在线程安全问题。但C++没有规定多个non-local static 对象的初始化顺序,尤其是来自多个编译单元的non-local static对象,他们的初始化顺序是随机的。

local static 对象(函数内)。初始化发生在控制流第一次执行到该对象的初始化语句时。多个线程的控制流可能同时到达其初始化语句。C++11之前,在多线程环境下local static对象的初始化并不是线程安全的。C++11规定,在一个线程开始local static 对象的初始化后到完成初始化前,其他线程执行到这个local static对象的初始化语句就会等待,直到该local static 对象初始化完成。

class Singleton
{
private:
    Singleton() { };
    ~Singleton() { };
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);
public:
    static Singleton& getInstance() 
        {
        static Singleton instance;
        return instance;
    }
};
上一篇 下一篇

猜你喜欢

热点阅读