2020-7-23 枚举实现单例模式和取代判断

Posted yunxingyubu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020-7-23 枚举实现单例模式和取代判断相关的知识,希望对你有一定的参考价值。

总所周知,枚举实现单例模式是最好的。
技术图片

这样实现的好处为:每个枚举类型及其定义的枚举变量在JVM中都是唯一的
所以我们不用new 也不用加逻辑判断 就能得到唯一实例了。只要类的类型是enmu不是class
那么如何实现呢?
教程

实现很简单,理解起来有
点难度,我们只需要知道 枚举类似于类变量那种,不能new 而且唯一
我们看起来似乎里面声明枚举属性是多余的,但是事实上枚举虽然不能new 但是
枚举属性才是它的一个实例,如果没有属性 枚举也无法使用。

枚举代替判断
好处:不用怕写错了 对于记录一个事务的多个状态有非常大的好处
摆脱之前使用的if语句和switch语句:

public class Pizza {

    private PizzaStatus status;
    public enum PizzaStatus {
        ORDERED (5){
      //5为枚举代表的状态码
            @Override
            public boolean isOrdered() {
                return true;
            }
        },
        READY (2){
            @Override
            public boolean isReady() {
                return true;
            }
        },
        DELIVERED (0){
            @Override
            public boolean isDelivered() {
                return true;
            }
        };

        private int timeToDelivery;

        public boolean isOrdered() {return false;}

        public boolean isReady() {return false;}

        public boolean isDelivered(){return false;}

        public int getTimeToDelivery() {
            return timeToDelivery;
        }

        PizzaStatus (int timeToDelivery) {
            this.timeToDelivery = timeToDelivery;
        }
    }

    public boolean isDeliverable() {
        return this.status.isReady();
    }

    public void printTimeToDeliver() {
        System.out.println("Time to delivery is " + 
          this.getStatus().getTimeToDelivery());
    }

    // Methods that set and get the status variable.
}

测试代码

@Test
public void givenPizaOrder_whenReady_thenDeliverable() {
    Pizza testPz = new Pizza();
    testPz.setStatus(Pizza.PizzaStatus.READY);
    assertTrue(testPz.isDeliverable());
}

技术图片

代码解析:
1、枚举方法
enmu[ 方法[abs]() 枚举1(代表的状态)[覆写方法] ]

2、PizzaStatus 其实已经有三个 不同状态的实例了 不需要new
3、Pizza.PizzaStatus.READY 其实是就是一个PizzaStatus的实例
这个实例中重写了isReady() 方法
4、什么时候 修改了 技术图片
这是一个很难理解的问题,枚举属性的参数似乎并没有和timeToDelivery交互
唯一的交互接口是 PizzaStatus (int timeToDelivery) {这个构造函数
为了解决问题,我们用eclipse来查看这个构造函数的调用
技术图片
技术图片
我们可以发现其实在我们使用Pizza.PizzaStatus.READY的时候其实以后调用了这个构造函数 并且传入了值,
这个值就是枚举属性的参数
换言之,每个枚举属性 其实都是一个 调用了enmu类型构造函数 的实例(子类)
所以我们才可以枚举属性中复写enmu类型的方法。(我们把它看成一个全新的子类的实例就好了)

枚举是什么
枚举像某种特定类型的许多不同实例的集合 和继承覆盖类似

枚举的全局唯一性
我们看例子
技术图片

我们可以发现Pizza.PizzaStatus.READY 和testPz.getStatus()是一致的。
也就是说如果我们再new一个对象 Pizza.PizzaStatus.READY这个实例也是和前一个一样的。
我们再也无法将Pizza.PizzaStatus.READY 重新new出来了,这就是它的唯一性。





























以上是关于2020-7-23 枚举实现单例模式和取代判断的主要内容,如果未能解决你的问题,请参考以下文章

Java 设计模式 -- 单例模式的实现(饿汉式枚举饿汉式懒汉式双检锁懒汉式内部类懒汉式)jdk 中用到单例模式的场景DCL实现单例需用volatile 修饰静态变量

Java 设计模式 -- 单例模式的实现(饿汉式枚举饿汉式懒汉式双检锁懒汉式内部类懒汉式)jdk 中用到单例模式的场景DCL实现单例需用volatile 修饰静态变量

如何对枚举类型实现的单例模式进行mock

单例模式_反射破坏单例模式_枚举类_枚举类实现单例_枚举类解决单例模式破坏

java GOF23涉及模式-单例模式-静态内部类实现和枚举实现

java GOF23设计模式-单例模式-枚举实现单例模式图(枚举是天然的单例)