设计模式思考之 Singleton 模式

174 阅读2分钟

这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战

这似乎是很多面试喜欢考的题,让面试者手写一个单例模式的实现。众所周知,茴香豆的茴字有4种写法,单例模式有7种写法。但茴香豆的case似乎是在讽刺,单例模式从技术原理上说并不是,只是不同场景可以用不同的实现,但有些写法是性能又好又安全,其他的写法似乎就没有必要了。

扯远了,还没有说单例模式的优势。这可能是这些设计模式中最好理解的一种,不用画类图,有些类全局使用,而且基本没有动态的东西,那么全局只创建一次就好了,就像spring的bean,就是单例的。毕竟某些固定的对象创建还是挺费事费力的,那么单例要做到的就是保证它确实只被创建一次,即使在多线程的环境下。另外就是,在某些场景下,有些类就只能创建一次,创建出第二个就会有bug,这也必须用到单例模式。

一般情况下,如果能写出以下的单例实现,就算这个问题过了。


public class SingletonObject {
    private SingletonObject(){}
    private static class InstanceHolder {
        private  final static SingletonObject instance = new SingletonObject();
    } 
    public static SingletonObject getInstance() {
        return InstanceHolder.instance;
    }
}

这是一种静态内部类的实现方式,基于Java类加载的机制,InstanceHolder在被使用之前不会被加载,同时也实现了懒加载。但这样并不算绝对安全,因为还是可能被反射或者反序列化获取多个实例。

如果你恰好看过《effective java》,作者会推荐使用枚举来实现单例。为什么呢?因为这是规定,俗话说玩赖。枚举类在jvm中保证只存在一个实例,无论怎么操作,都不能再创造出第二个一样的枚举类型。同时,枚举的写法写起来也特别精简:

public enum SomeThing { 
    INSTANCE; 
    public String getSomething() { 
        return "SomeThing"; 
    }  
}