面试题单例模式的五种写法(枚举妙用)

此文转载自:https://blog.csdn.net/aiailingfei/article/details/113098884#commentBox

设计模式之单例模式(单例模式的五种写法)

                         熊大

单例模式是23种设计模式之一并且属于创建型。
而且单例模式面试题经常出现 。那么接下来让我们看看单例模式得五种写法

第一种饿汉模式:

 public class Singleton {
    //关键字static 修饰类提前加载好
    private static final Singleton instance = new Singleton();
    //提供无参私有构造方法
    private Singleton() {
    }

    public static Singleton instance(){

        return instance;
    }
}

类加载得时候就已经被创建好了所以在创建得过程是线程安全得。
也许有人认为这种并不好因为它不是延迟加载得会占用内存。
其实事物都是双面性得如果是一个比较耗时得操作还是希望提前加载出来。

懒汉模式:

public class Singleton {
    private static Singleton instance ;
     //提供无参私有构造方法
    private Singleton() {
    }
    
    public static synchronized  Singleton getInstance(){

        if (null==instance){
            instance=new Singleton();
        }

        return instance;
    }

}

懒汉模式顾名思义是实例在用到的时候才去创建。

懒汉模式: 每次获取单例的时候加锁如果频繁使用会影响调用效率。
饿汉模式:初始化得时候加载会占用内存不支持延迟加载

双重校验模式:

public class Singleton {
    // 需要加上volatitle 防止指令重排
    private static volatile Singleton instance;

    private Singleton() { }
    
    public static Singleton getInstance(){
        //第一次校验如果为空
        if (null==instance){
          //对整个类进行加锁
            synchronized (Singleton.class){
                //初始化
                instance=new Singleton();
            }

        }

        return instance;
    }
}

从代码上看双重校验模式综合了懒汉、饿汉得优点即支持延时加载也不占用内存。线程也是安全得性能大幅提升。

内部静态类模式:

public class Singleton {

    private Singleton() { }

    // 内部静态类
    public static class SingletonHolder{

     private static final  Singleton instance=new Singleton();
    }

    public static  Singleton getInstance(){

        return SingletonHolder.instance;
    }

}

SingletonHolder 是一个内部静态类,当外部类 Singleton 被加载的时候,并不会创建 SingletonHolder 实例对象。只有当调用 getInstance() 方法时,SingletonHolder 才会被加载,这个时候才会创建 instance。instance 的唯一性、创建过程的线程安全性,都由 JVM 来保证。所以,这种实现方法既保证了线程安全,又能做到延迟加载。

枚举Enum:

public enum Singleton{
    INSTANCE;
    private void singleton(){
        
    }
}

枚举类型本身的特性保证了实例创建的线程安全性和实例的唯一性。

对于枚举还有许多妙用如我们在开发得时候经常会遇到状态的判断。

如对于一笔订单来说是成功、失败、处理中各有不同的逻辑处理也许有的人会用if,也许有的人会用switch 其实用枚举也可以搞定如下。

@Slf4j
public enum Singleton{
    SUCCESS {
        @Override
        public void doSomeThing() {
            log.info("处理成功时得方法");
        }
    },
    FAIL {
        @Override
        public void doSomeThing() {
            log.info("处理失败时得方法");
        }
    },
    PROCESSING {
        @Override
        public void doSomeThing() {
            log.info("处理中得方法");
        }
    };
    // 多个实现 职责单一
    public abstract void doSomeThing();
}

假如代码这样写是不是就可以根据它返回的状态直接这样写Singleton.valueOf(status).doSomeThing这样代码是不是比较简洁呢!

如有错误请添加微信指出或者评论指出
当然也寻找志同道合的同学一起进步下面是个人微信欢迎您的添加:

个人微信

   

更多内容详见微信公众号:Python测试和开发

Python测试和开发

原文地址:https://www.cnblogs.com/phyger/p/14331386.html