Enum支持序列化吗以及设计模式策略枚举

背景

  1. Enum是否支持序列化,以及底层的实现原理
  2. Enum类型的策略枚举这种设计模式如何实现和优缺点

Enum支持序列化吗

支持,在Java中,只要一个类实现了java.io.Serializable接口,那么它就可以被序列化。

Enum底层实现

当我们使用enmu来定义一个枚举类型的时候,编译器会自动帮我们创建一个final类型的类继承Enum类,所以枚举类型不能被继承,这个类中有几个属性和方法都是static类型的,因为static类型的属性会在类被加载之后被初始化,当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的。所以,创建一个enum类型是线程安全的。

一旦实现了Serializable接口之后,就不再是单例得了,因为,每次调用 readObject()方法返回的都是一个新创建出来的对象,有一种解决办法就是使用readResolve()方法来避免此事发生。但是,为了保证枚举类型像Java规范中所说的那样,每一个枚举类型极其定义的枚举变量在JVM中都是唯一的,在枚举类型的序列化和反序列化上,Java做了特殊的规定。

在序列化的时候Java仅仅是将枚举对象的name属性输出到结果中,反序列化的时候则是通过java.lang.Enum的valueOf方法来根据名字查找枚举对象。同时,编译器是不允许任何对这种序列化机制的定制的,因此禁用了writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法。原文参考深度分析 Java 的枚举类型

设计模式之策略枚举

策略模式定义

定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也称为政策模式(Policy)。(Definea family of algorithms,encapsulate each one, andmake them interchangeable. Strategy lets the algorithmvary independently from clients that use it. )

这里写图片描述

从以上官方定义分析到策略模式具有三个角色分别是:
- 环境类(Context):(如上图中的Context,根据不同的使用环境调用不同的策略接口)
- 抽象策略类(Strategy):(策略接口,如上图中的Strategy)
- 具体策略类(ConcreteStrategy):(实现策略接口的类:如上图中的ConcreteStrategyA,B,C)

策略举例

以加减法为例来划分一下其中的角色,比如 加法:1+1=2,减法1-1=0。
可以抽象出来为除了加减的符号不同其他都是一样的:两个参数,一操作符号,和返回值。
因此可以定义个接口

参考源码作者: 策略模式(政策模式) 策略枚举

/** 
 * 定义策略接口(一组策略) 
 * @author yanwenfei 
 * 
 */  
public interface IStrategy {  

    //策略需要执行的方法  
    public int exec(int a, int b);  
} 

接下来实现加减的两个具体算法

/** 
 * 策略A加法 
 * @author yanwenfei 
 * 
 */  
public class StrategyADD implements IStrategy {  

    @Override  
    public int exec(int a, int b) {  
        return a+b;  
    }  

}  


/** 
 * 减法策略 
 * @author yanwenfei 
 * 
 */  
public class StrategySub implements IStrategy {  

    @Override  
    public int exec(int a, int b) {  
        return a - b;  
    }  

}  

策略封装,而高层不用知道具体是哪种策略,只需要调用抽象策略的方法即可

/** 
 * 策略环境即封装
 * @author yanwenfei 
 */  
public class Calculator {  

    private IStrategy strategy;  

    //切换策略  
    public Calculator(IStrategy strategy) {  
        this.strategy = strategy;  
    }  

    //执行策略方法  
    public int exec(int a, int b){  
        return strategy.exec(a, b);  
    }  
}  

策略调用

public class TestMain {  

    public static void main(String[] args) {  

        Calculator calculator = null;  

        IStrategy streadd = new StrategyADD();//创建加法策略;  
        calculator = new Calculator(streadd);//切换策略  
        int add = calculator.exec(20, 30);  
        System.out.println("20 + 30 = " + add);  

        IStrategy stresub = new StrategySub();//创建减法策略;  
        calculator = new Calculator(stresub);//切换策略  
        int sub = calculator.exec(20, 30);  
        System.out.println("20 - 30 = " + sub);  
    }  

}  

以上为策略模式传统的实现方式,肯定很多人能看出来这个策略模式有很多缺点,虽然便于扩展,但是每一个策略都是一个类,这个先不说,下来看一下更简略的策略枚举。

策略枚举

/** 
 * 策略枚举 
 * @author yanwenfei 
 */  
public enum Calculator {  



    ADD("+") {  
        @Override  
        public int exec(int a, int b) {  
            // TODO Auto-generated method stub  
            return a+b;  
        }  
    },  

    SUB("-") {  
        @Override  
        public int exec(int a, int b) {  
            // TODO Auto-generated method stub  
            return a-b;  
        }  
    };  


    public abstract int exec(int a, int b);  

    //运算符  
    private String value = "";  

    private Calculator(String value) {  
        this.value = value;  
    }  

    public String getValue() {  
        return value;  
    }  

}  

调用策略

public class TestMain {  

    public static void main(String[] args) {  

        int add = Calculator.ADD.exec(10, 30);  
        System.out.println("10 + 30 = "+add);  

        int sub = Calculator.SUB.exec(10, 30);  
        System.out.println("10 - 30 = "+sub);  
    }  
}  

策略模式优缺点

策略模式优点
- 算法可以自由切换(高层屏蔽算法,角色自由切换)
- 避免使用多重条件判断(如果算法过多就会出现很多种相同的判断,很难维护)
- 扩展性好(可自由添加取消算法 而不影响整个功能)

策略模式缺点
- 策略类数量增多(每一个策略类复用性很小,如果需要增加算法,就只能新增类)
- 所有的策略类都需要对外暴露(使用的人必须了解使用策略,这个就需要其它模式来补充,比如工厂模式、代理模式)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值