美文网首页
设计模式之单例模式

设计模式之单例模式

作者: 老羊_肖恩 | 来源:发表于2017-06-04 20:47 被阅读26次

    单例模式的定义

    Ensure a class has only one instance, and provide a global point of access to it. 即确保某各类只有一个实例,并且提供一个全局的入口。
    通用类图如下:

    Singleton.jpg

    Singleton类称为单例类,通过使用私有构造方法确保在系统中只产生一个实例。按照实例初始化的时间,单例模式可以分成两类:饿汉式单例模式和懒汉式单例模式。顾名思义:恶汉式单例模式是在类加载时便完成单例实例的创建,而懒汉式单例模式是在使用时,才进行单例实例的创建。代码分别如下:

    • 饿汉式
    public class Singleton {
        private static final Singleton singleton = new Singleton();
    
        //私有构造方法
        private Singleton(){
        }
    
        //获取实例对象方法
        public static Singleton getSingleton(){
            return singleton;
        }
    
        //其他方法,尽量是static
        public static void doSomething(){   
        }
    }
    
    • 懒汉式
    public class Singleton {
        
        private static Singleton singleton = null;
        
        //私有构造方法
        private Singleton(){
        }
        
        //获取实例对象方法
        public static Singleton getSingleton(){
            if(singleton == null){
                //考虑高并发情况
                synchronized (Singleton.class) {
                    if(singleton == null){
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
        
        //其他方法,尽量是static
        public static void doSomething(){
            
        }
    }
    

    饿汉式单例模式和懒汉式单例模式均有各自的试用场景,只是懒汉式单例模式在第一次创建单例实例时,需考虑在高并发场景下可能会在内存中创建多个实例的情况。两种实现方式可以根据需要自行选择,推荐试用恶汉式单例模式。

    单例模式的应用

    1. 单例模式的有点
    • 由于单例模式在内存中只有一个实例,因此内存开支较小。
    • 由于单例模式只需生成一次实例,因此会大大减少系统的性能开销。当一个对象需要频繁创建创建和销毁,且创建和销毁的性能无法优化时,单例模式的优势尤为明显。
    • 单例模式可以避免对资源的多重占用。
    • 单例模式可以在系统设置全局的访问点,优化和共享资源访问。
    1. 单例模式的缺点
    • 单例模式一般没有接口,很难扩展。
    • 单例模式不利于测试。在并行开发环境中,如果单例模式没有完成,是不能进行测试的,没有接口也不能使用mock的方式虚拟一个对象。
    • 单例模式与单一职责原则(SRP)有冲突。单一职责原则要求一个类应该只实现一个逻辑,而不关心它是否是单例,是不是要单例应取决于环境,而单例模式把“要单例”和业务逻辑融合在一个类中。
    1. 单例模式使用场景
    • 要求生产唯一序列号的环境。
    • 系统或项目中的共享资源。
    • 创建一个资源系统开销较大。
    • 需要定义搭理静态常量和静态方法的环境,可以采用单例模式。
    1. 单例模式的注意事项
    • 线程安全。高并发情况下,懒汉式单例模式需要考虑线程安全问题,即有两个或以上线程同时去创建单例实例。
    • 单例的复制。在Java中,对象默认是不可以复制的,若实现了Cloneable接口,并且实现了clone方法,则可以直接通过对象复制的方式创建一个新对象,此时对象复制是不需要调用构造方法的,因此即使是私有的构造方法,此时的对象依然可以被复制。因此单例类最好不要实现Cloneable接口。

    最佳实践

    单例模式是23中设计模式中比较简单的设计模式,应用也十分广泛。在Spring中,每个Bean默认都是单例的,这样做的优点是Spring的Bean容器可以管理这些Bean的生命周期。如果采用非单例模式(Prototype), 则Bean初始化之后交由J2EE容器管理,Spring容器不在跟踪管理这些Bean的生命周期。

    《注》以上内容总结自秦小波-《设计模式之禅》,仅为个人学习笔记。

    相关文章

      网友评论

          本文标题:设计模式之单例模式

          本文链接:https://www.haomeiwen.com/subject/zhkbfxtx.html