前言
最近就是想再学设计模式,所以稍微总结下。这篇我们主要是说单例模式,这对于开发来说基本是用过,下面虽然有好几种实现,但一般还是饿汉式的实现方式工作中最常使用。如果可以确保此类是全局可⽤不需要做懒加载,那么直接创建并给外部调⽤即可, 但如果是很多的类,需要触发⼀定的条件后才显示,那么⼀定要⽤懒加载。 线程的安全上可以按需选择。
概念
单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。
类型
- 饿汉式:在类加载时已经创建好该单例对象,等待被程序使用
- 懒汉式:在真正需要使用对象时才去创建该单例类对象
- *枚举式: 与饿汉式一样在加载时已经创建。可以防止利用反射强行构建单例对象,而且可以在枚举类对象被反序列化的时候,保证反序列的返回结果是同一对象(此方法是:effactive java作者写的)
代码实现
饿汉式
python实现饿汉式
# 饿汉式
class Singleton(object):
# 重写创建实例的__new__方法
def __new__(cls):
# 如果类没有实例属性,进行实例化,否则返回实例
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__new__(cls)
return cls.instance
java实现饿汉式
// 饿汉式
public class Singleton{
private static final Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance() {
return singleton;
}
}
懒汉式
python实现懒汉式
# 懒汉式
class Singleton(object):
__instance = None
def __init__(self):
if not self.__instance:
print('调用__init__, 实例未创建')
else:
print('调用__init__,实例已经创建过了:', __instance)
@classmethod
def get_instance(cls):
# 调用get_instance类方法的时候才会生成Singleton实例
if not cls.__instance:
cls.__instance = Singleton()
return cls.__instance
java懒汉式
// 懒汉式---这种方式消耗资源多,不建议使用
public class Singleton {
private Singleton() {} //私有构造函数
//单例对象 volatile -->阻止变量访问前后的指令重排,保证指令执行的顺序
private volatile static Singleton instance = null;
//双重检测机制 -->两次因为线程执行很快,不能保证只实例化一次
public static Singleton getInstance() {
if (instance == null) {
// 保证了线程安全
synchronized (Singleton.class){
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
枚举式
// 枚举
// 这种是java作者之一写的,是目前最好的,防止利用反射强行构建单例对象,而且可以在枚举类对象被反序列化的时候,保证反序列的返回结果是同一对象
public enum SingletonEnum {
INSTANCE;
}
其他实现方式
python-基于metaclass方式实现
import threading
class SingletonType(type):
_instance_lock = threading.Lock()
def __call__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
with SingletonType._instance_lock:
if not hasattr(cls, "_instance"):
cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)
return cls._instance
class example(metaclass=SingletonType):
def __init__(self,name):
self.name = name
python-类(classmethod)
class Singleton(object):
def __init__(self):
pass
@classmethod
def instance(cls, *args, **kwargs):
if not hasattr(Singleton, "_instance"):
Singleton._instance = Singleton(*args, **kwargs)
return Singleton._instance
python-装饰器
def singleton(cls, *args, **kw):
instances = {}
def _singleton():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return _singleton
@singleton
class Example(object):
def __init__(self):
pass
java-静态内部类
public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
优缺点
优点
- 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例
- 避免对资源的多重占用(比如写文件操作,数据库的连接等)
缺点
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化
学习链接
菜鸟-单例模式(菜鸟说的也很详细= = ||)
既然无处可逃,不如喜悦。既然没有净土,不如静心。既然没有如愿,不如释然。