JS和Java的单例模式
设计模式是一个必须要掌握的内容,就好像武学的固定招式一样,设计模式在使用中都有一些固定的套路,掌握好套路才能少走弯路。这一篇介绍一下简单但是使用频率比较高的单例模式
javascript单例模式
由于js是单线程的,不需要考虑多线程的单例实现情况,比较简单。我们可以通过闭包实现js的单例。详细代码如下
class Singleton {
constructor(){
this.state = 'hide'
}
show(){
if (this.state==='show'){
console.log('你已经打开了窗口')
return
}
this.state = 'show'
}
hide(){
if (this.state==='hide'){
console.log('你已经关闭了窗口')
return
}
this.state = 'hide'
}
}
Singleton.getInstance = (function () {
let instance = null
return function () {
if (instance===null){
instance = new Singleton()
}
return instance
}
})()
const instance = Singleton.getInstance()
const instance2 = Singleton.getInstance()
console.log(instance===instance2) //true
instance.show()
instance.show() //你已经打开了窗口
这里由于js没有静态属性的概念,所以通过闭包实现了实例instance
的静态化,第一次通过自调用函数形成闭包,然后在每一次调用的时候判断实例是否已经初始化,如果有直接返回即可。
Java单例模式
Java中需要考虑多线程,序列化,反射等问题,常见的实现模式有饿汉式,懒汉式,静态内部类式,枚举,双重检查等等。
这里介绍一个综合了饿汉式,懒汉式,并且能够支持序列化和反序列化的单例设计方法
package com.natsuki;
import java.io.Serializable;
public class StaticInnerClassSingleton implements Serializable {
private static class InnerClass {
private static StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return InnerClass.instance;
}
private StaticInnerClassSingleton() {
}
/**
* 序列化和反序列化的问题
* @return 单例
*/
private Object readResolve() {
return InnerClass.instance;
}
}
这在一般的工程编码中已经完全够用了,既能延迟加载,又保证了线程安全,同时还支持序列化。