引入
一个类被设计出来,就意味着它具有某种行为(方法),属性(成员变量)。一般情况下,当我们想使用这个类时,会使用 new 关键字,这时候 jvm 会帮我们构造一个该类的实例。这么做比较耗资源。如果能在 jvm 启动时就 new 好。或者是某一次 new 好后,之后就 不用 new 了。这样就比较节省资源。
这就是单例模式要解决的问题。
单例实现步骤
要实现一个单例类,需要经过三个步骤:
- 私有化构造函数,目的是避免其它类可以创建这个类的对象;
- 在本类中创建唯一实例对象(因为构造函数私有化了,所以单例类的唯一实例对象只能在单例类里面创建),使用一个私有静态的成员变量保存。
- 对外提供一个公开的静态的函数供别人获取这个唯一的实例对象。
实例的两种实现方法:
- 饿汉式
特定:在加载类的同时就创建了这个类的唯一实例;
好处:可以保证这个类的实例的唯一性;
弊端:如果只是使用这个类,但是暂时不需要它的对象,也会创建唯一实例,造成内存的浪费。
public class Single {
// 1 私有化构造函数
private Single() {}
// 2 在本类中创建唯一实例对象,使用私有静态成员变量保存
priave static Single ss = new Single();
// 对外提供公开的静态的获取方法
public static Single getInstance() {
return ss;
}
}
public class SingleDemo {
priavte SingleDemo() {
System.out.pintln("创建单例对象...");
}
private static SingleDemo ss = new SingleDemo();
public static SingleDemo getInstance() {
return ss;
}
// 单例类中,可以有其他属性和行为
public staticvoid show() {
Systemc.out.println("我是单例类中的一个静态函数")
}
}
public class SingleTest {
public static void main(String[] args) {
// 调用单例类中的静态函数 show
SingleDemo.show();
}
}
- 懒汉式
特点:在第一次调用获取实例的方法时才创建对象;
好处:第一次调用获取实例的方法时才创建对象,可以避免内存的浪费;
弊端:多线程环境下不能保证实例的唯一性;
public class Single2 {
// 私有化构造函数
private Single2() {}
// 在本类中创建唯一实例对象,使用一个私有静态成员变量保存
private static Single2 ss = null;
// 对外提供一个公开静态的获取方法
public static Single2 getInstance() {
if (ss == null) {
ss = new Single2();
}
return ss;
}
}
public class SingleDemo2 {
private SingleDemo2() {
System.out.println("创建单例对象...")
}
private static SingleDemo2 ss = null;
public static SingleDemo2 getInstance() {
if (ss == null) {
ss = new SingleDemo2();
}
return ss;
}
// 单例中,可以有其他属性和行为
public static void show() {
System.out.println("我是单例类SingleDemo2中的一个静态函数");
}
}
public class SingleTest2 {
public static void main(String[] args) {
// 调用单例类中的静态函数 show
SingleDemo2.show();
SingleDemo2 s1 = SingleDemo2.getInstance();
SingleDemo2 s2 = SingleDemo2.getInstance();
System.out.println(s1);
System.out.println(s2);
}
}
单例模式的优点
- 严格控制对唯一的访问方式
- 仅有一个实例,可以节约系统资源
单例模式的缺点
- 单例模式没有抽象层,扩展比较困难
- 职责过重,即充当工厂角色,又充当产品角色
- 如果长期不使用,Java会自动回收,导致下次使用又重新实例化
单例模式的特点
- 有仅有一个单例类实例(无法通过反序列化重新构建对象)
- 构造函数私有化
- 通过静态方法或枚举获取单例类实例
示例代码
class Test:
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super(Test, cls).__new__(cls)
return cls.instance
obj1 = Test()
obj2 = Test()
print(obj1 is obj2)
def singleton(cls):
instances = {}
def getinstance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return getinstance
@singleton
class MyClass:
a = 1
c1 = MyClass()
c2 = MyClass()
print(c1 == c2)
网友评论