っ碎片化代码IT@程序员猿媛

A02—单例模式(Singleton Pattern)

2019-04-19  本文已影响0人  白晓明

单例模式(Singleton Pattern) 是Java中最简单的设计模式之一,其定义如下:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。简单而言单例类只能有一个实例,这个实例是自己创建的唯一实例,然后提供全局访问的方法。

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问方式。
主要解决: 一个全局使用的类频繁创建和销毁。
何时使用: 控制实例数目,节省系统资源时。
如何解决: 判断系统是否已经有这个实例,如果存在则返回,否则创建。
关键代码: 将构造函数设为私有,并提供全局方法,在此方法中对实例进行判断是创建还是直接使用。
优点: 减少内存开销,避免对资源的多重占用。
缺点: 没有接口,扩展很困难;对测试不利;与单一职责原则冲突。
应用实例: 一个班级只有一个班主任(不考虑其他外界因素)

我们创建一个ClassTeacher类,通过定义一个私有访问权限的构造函数,防止其他类new出来一个对象,并提供getInstance()方法,在该方法中实例化一个自己的对象。

/**
 * 班主任类
 * @author 丶白小源
 *
 */
public class ClassTeacher {

    //创建班主任的一个私有对象
    private static final ClassTeacher instance = new ClassTeacher();
    //为了该类不被实例化,提供私有构造函数
    private ClassTeacher(){
        //不考虑外界因素,班级班主任一直不变
    }
    
    //提供全局方法
    public static ClassTeacher getInstance() {
        return instance;
    }
    
    //班主任讲话
    public void say() {
        System.out.println("今天XXX同学表现很好!");
    }
}

班主任每天管理学生学习情况,对学生一周的情况进行表彰。

/**
 * 学生类
 * @author 丶白小源
 *
 */
public class Student {

    public static void main(String[] args) {
        //一周五天学生见到的班主任都是同一人
        for (int i = 0; i < 5; i++) {
            ClassTeacher ct = ClassTeacher.getInstance();
            ct.say();
        }
    }
}
//结果
今天XXX同学表现很好!
今天XXX同学表现很好!
今天XXX同学表现很好!
今天XXX同学表现很好!
今天XXX同学表现很好!

单例模式的几种实现方式

(1)懒汉式,线程不安全
public class ClassTeacher {

    //创建班主任的一个私有对象
    private static ClassTeacher instance = null;
    //为了该类不被实例化,提供私有构造函数
    private ClassTeacher(){
        //不考虑外界因素,班级班主任一直不变
    }
    
    //提供全局方法
    public static ClassTeacher getInstance() {
        if(instance == null) {
            instance = new ClassTeacher();
        }
        return instance;
    }
}
(2)懒汉式,线程安全
public class ClassTeacher {

    //创建班主任的一个私有对象
    private static ClassTeacher instance = null;
    //为了该类不被实例化,提供私有构造函数
    private ClassTeacher(){
        //不考虑外界因素,班级班主任一直不变
    }
    
    //提供全局方法
    public static synchronized ClassTeacher getInstance() {
        if(instance == null) {
            instance = new ClassTeacher();
        }
        return instance;
    }
}
(3)饿汉式,线程安全
public class ClassTeacher {

    //创建班主任的一个私有对象
    private static ClassTeacher instance = new ClassTeacher();
    //为了该类不被实例化,提供私有构造函数
    private ClassTeacher(){
        //不考虑外界因素,班级班主任一直不变
    }
    
    //提供全局方法
    public static synchronized ClassTeacher getInstance() {
        return instance;
    }
}
(4)双检锁/双重效验锁(DCL,即double-checked locking)
public class ClassTeacher {

    //创建班主任的一个私有对象
    private static ClassTeacher instance = null;
    //为了该类不被实例化,提供私有构造函数
    private ClassTeacher(){
        //不考虑外界因素,班级班主任一直不变
    }
    
    //提供全局方法
    public static ClassTeacher getInstance() {
        if(instance == null) {
            synchronized (ClassTeacher.class) {
                instance = new ClassTeacher();
            }
        }
        return instance;
    }
}
(5)登记式/静态内部类
public class ClassTeacher {

    private static class ClassTeacherHolder {
        private static final ClassTeacher INSTANCE = new ClassTeacher();
    }

    //为了该类不被实例化,提供私有构造函数
    private ClassTeacher(){
        //不考虑外界因素,班级班主任一直不变
    }
    
    //提供全局方法
    public static ClassTeacher getInstance() {
        return ClassTeacherHolder.INSTANCE;
    }
}
(6)枚举
public enum ClassTeacher {

    INSTANCE;
    
    public ClassTeacher getInstance() {
        return INSTANCE;
    }
}

编译完成后相当于:

public final class ClassTeacher extends Enum<ClassTeacher> {

    public static final ClassTeacher CLASSTEACHER;
    public static ClassTeacher[] values();
    public static ClassTeacher valueOf(String s);
    static{};
}

参考:
设计模式简介
设计模式之禅

上一篇 下一篇

猜你喜欢

热点阅读