. 没人看的前言

  枚举相信大家都不陌生,在日常的开发中,我们在大多数情况下使用枚举一般是为了罗列既定的属性值,作用其实与常量差别不大,但枚举的优势在于,可以定义多种类型的多个常量,自由度和扩展度会大大高于普通常量,而且阅读起来会比常量更加直观,因为枚举内的属性不一定全部都要用到,一般在定义枚举时都会添加一个注释key,也就是此枚举值的说明字段。那么既然枚举可自由扩展,在开发中,我们就可以利用枚举来减少繁琐的代码步骤,甚至解决某些难题。

1.使用枚举扩展属性

  举个常见的例子:

Excel导出统计数据,其中,Excel内容包括标题、子标题、内容,标题、子标题格式已知

 Excel导出,封装数据时,很多人习惯直接在方法体里拼接,这么做后患无穷,最大的两个影响:可读性差、扩展性差,我们可能经常会需要客户该改需求的情况,如果客户提出想要在Excel里加个字段或者换下位置,可能会让人头大。

 那么利用枚举,我们可以很好的解决这点。先看枚举实例:

 其中,每个枚举值代表一个标题,xxxHead为子标题,xxxField为内容字段,如此一来,Excel的内容便有了一个初步的概图,接下来写入数据也就清晰明了了

/**
 * @description:分析数据Excel数据枚举
 */
public enum AnalysisExcelDataType {

    DATE("date","/",  dataInEnum.dateHead, dataInEnum.dateField),
    SHOP("shop","店铺首页",  dataInEnum.shopHead, dataInEnum.shopField),
    GOODS("goods","商品页", dataInEnum.goodsHead, dataInEnum.goodsField),
    PAGE("page","落地页面", dataInEnum.pageHead, dataInEnum.pageField),
    CUSTOMER("customer","客户行为", dataInEnum.customerHead, dataInEnum.customerField),
    ORDER("order","下单", dataInEnum.orderHead, dataInEnum.orderField),
    PAY("pay","付款", dataInEnum.payHead, dataInEnum.payField),
    COUPON("coupon","优惠券", dataInEnum.couponHead, dataInEnum.couponField);

    private String title;
    private String titleName;
    private String[] headStrData;
    private String[] fieldStrData;
    AnalysisExcelDataType(String title, String titleName, String[] headStrData, String[] fieldStrData){
        this.title = title;
        this.titleName = titleName;
        this.headStrData = headStrData;
        this.fieldStrData = fieldStrData;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getTitleName() {
        return titleName;
    }

    public void setTitleName(String titleName) {
        this.titleName = titleName;
    }

    public String[] getHeadStrData() {
        return headStrData;
    }

    public void setHeadStrData(String[] headStrData) {
        this.headStrData = headStrData;
    }

    public String[] getFieldStrData() {
        return fieldStrData;
    }

    public void setFieldStrData(String[] fieldStrData) {
        this.fieldStrData = fieldStrData;
    }
}

class dataInEnum{
    public static final String[] dateHead = {"日期"};
    public static final String[] dateField = {"dataTime"};

    public static final String[] shopHead = {"PV","UV"};
    public static final String[] shopField = {"shopPvNum","shopUvNum"};

    public static final String[] goodsHead = {"PV","UV"};
    public static final String[] goodsField = {"skuPvNum","skuUvNum"};

    public static final String[] pageHead = {"PV","UV"};
    public static final String[] pageField = {"pv","uv"};

    public static final String[] customerHead = {"加购商品人数","收藏商品人数","收藏店铺人数"};
    public static final String[] customerField = {"cartNum","followSkuNum","followShopNum"};

    public static final String[] orderHead = {"下单人数","下单金额","下单订单数","下单件数"};
    public static final String[] orderField = {"ordPins","ordAmount","ordNum","ordQtty"};

    public static final String[] payHead = {"付款人数", "付款金额", "付款订单数", "付款件数"};
    public static final String[] payField = {"payPins","payAmount","payNum","payQtty"};

    public static final String[] couponHead = {"领券人数", "用券人数", "引入订单量", "引入金额"};
    public static final String[] couponField = {"couponPins","couponUsePins","couponOrders","couponAmount"};
}

枚举创建好后,开始写入数据,这里为了可读性和方便(主要~),将标题与内容分开写入,先看标题:

 

/**
*Excel标题、子标题写入
*/
 private static LinkedHashMap createTitle(HSSFSheet sheet){
        String[] head = null;
        String[] field = null;
        //标题
        LinkedHashMap<String, String>  headMap = new LinkedHashMap<>();
        //子标题
        LinkedHashMap<String, String> headMap2 = new LinkedHashMap<>();
        List<Integer> colspanList = new ArrayList<>();
        int cloCount = -1;
        //遍历标题枚举
        for(AnalysisExcelDataType dataType : AnalysisExcelDataType.values()){
            head = dataType.getHeadStrData();
            field = dataType.getFieldStrData();
            for(int i=0;i<head.length;i++){
                headMap2.put(field[i], head[i]);
            }
            headMap.put(dataType.getTitle(), dataType.getTitleName());
            if(head.length > 1){
                //标题跨行 每个标题跨的行数为子标题个数
                sheet.addMergedRegion( new CellRangeAddress(0,0,cloCount+1, cloCount + head.length));
            }
            colspanList.add(head.length);
            cloCount += head.length;
        }
     //样式
        HSSFCellStyle style = ExcelExtUtil.createCellStyle(true, true,(short)11,
                null, HorizontalAlignment.CENTER);
        //标题
        ExcelExtUtil.writeSheetTitle(sheet, headMap, 0, colspanList, style);
        style = ExcelExtUtil.createCellStyle(true, true,null,
                null, HorizontalAlignment.CENTER);
        //子标题
        ExcelExtUtil.writeSheetTitle(sheet, headMap2, 1, null,style);
        return headMap2;
    }

这里使用了poi进行写入,有部分代码因为考虑篇幅没有贴出来,毕竟不是本文重点,如果有需要可以留言。

好,标题写入完毕,开始写入数据,方式与标题大同小异,利用循环,根据field查询数据内的字段值

这里的JSONArray就是普通的po集合

 private void createSumExcelData(JSONArray dataArray){
        String[] head = null;
        String[] field = null;
        List<Map<String, Object>> mapList = new ArrayList<>();
        Map<String, Object> map = null;
        JSONObject jsonObject = null;
        HSSFSheet sheet = ExcelExtUtil.createSheet("统计数据");
        //标题数据 同上
        LinkedHashMap<String, String>  headMap = createTitle(sheet);
        for(Object object : dataArray){
            map = new HashMap<>();
            for(AnalysisExcelDataType dataType : AnalysisExcelDataType.values()){
                head = dataType.getHeadStrData();
                field = dataType.getFieldStrData();
               for(int i=0;i<head.length;i++){
                   //根据标题对应字段获取数据中的值
                   jsonObject = JSONObject.parseObject(JSONObject.toJSONString(object));
                   map.put(field[i], jsonObject.get(field[i]));
                }
            }
            mapList.add(map);
        }
        HSSFCellStyle style = ExcelExtUtil.createCellStyle(false, true,null,
                null, HorizontalAlignment.CENTER);
        //数据
        ExcelExtUtil.writeSheetData(sheet, headMap, mapList, 2, style);
    }

如此一来,如果Excel需要变动,那么只需要改动枚举即可,数据封装主体完全不需要改动,是不是很优雅了呢~~

 

2.枚举配合多态

 话不多说,让我们先看一个需求例子:

现需要开发一个消息通知工具类,需要透出统一发送方法和单一发送方法,并支持多渠道消息通知,且渠道间的入参有差异

 我的做法是使用多态,继承关系来实现多渠道消息发送,并提供统一调用入口。

  暂定两个发送渠道:短信、邮件,其中,Dto类如下:

枚举类的扩展使用
import lombok.Data;
/**
 * @author :shenzhikui
 * @description:渠道参数传输对象父类
 * @date :2019/8/12
 */
//lombok 自动生成getter、setter、toString
@Data
public abstract class BaseNotifyDto {
    private String recipient; //接收人
    private String content; //内容
}
BaseNotifyDto

相关文章:

  • 2021-02-08
  • 2022-12-23
  • 2021-12-06
猜你喜欢
  • 2022-01-05
  • 2021-10-13
  • 2018-12-11
  • 2022-12-23
  • 2022-12-23
  • 2021-10-07
  • 2022-12-23
相关资源
相似解决方案