使用Java枚举类优化工厂方法

使用Java枚举类优化工厂方法

背景

最近在工作中遇到一个需求,需要把不同的统计报表导出成csv文件,经过一系列抽象过后,发现不同的导出类型,还是需要不同的service来进行处理,这样就会导致工厂方法存在大量的if else或者switch case语句,这样看起来代码非常臃肿,不便于后面维护,于是使用枚举类进行重构,在此记录一下。

场景

在没有进行改动的时候,代码是这样的:

 private Collection<String[]> initData(ExportParam exportParam, Exportkey v) &#123;
        Collection<String[]> data = null;
        switch (v) &#123;
            case CONTENT_HISTORY_LIST:
                data = applicationContext.getBean(HistoryContentCsvDataServiceImpl.class).initData(exportParam);
                break;
            case CONTENT_CAPACITY_STATS:
                data = applicationContext.getBean(ContentCapacityStatsServiceImpl.class).initData(exportParam);
                break;
            case CONTENT_AMOUNT_STATS:
                data = applicationContext.getBean(ContentAmountStatsServiceImpl.class).initData(exportParam);
                break;
            case DEVICE_ONLINE_RATE_STATS:
                data = applicationContext.getBean(DeviceOnlineRateServiceImpl.class).initData(exportParam);
                break;
            case DEVICE_ONLINE_DETAIL_LIST:
                data = applicationContext.getBean(DeviceOnlineDetailServiceImpl.class).initData(exportParam);
                break;
            case PLAY_COUNT_CONTENT_STATS:
                data = applicationContext.getBean(PlayCountContentStatsServiceImpl.class).initData(exportParam);
                break;
            case PLAY_COUNT_DEVICE_STATS:
                data = applicationContext.getBean(PlayCountDeviceStatsServiceImpl.class).initData(exportParam);
                break;
           ... 省略部分代码
        &#125;

        return data;
    &#125;

这里面使用了switch语句进行判断,不同的case拿到不同的bean,导致代码很长,于是对Exportkey这个枚举类进行改造。

public enum Exportkey &#123;
    CONTENT_HISTORY_LIST,
    CONTENT_CAPACITY_STATS,
    CONTENT_AMOUNT_STATS,
    DEVICE_ONLINE_RATE_STATS,
    DEVICE_ONLINE_DETAIL_LIST,
    PLAY_COUNT_CONTENT_STATS,
    PLAY_RECORD_CONTENT_DETAIL_STATS,
    PLAY_COUNT_DEVICE_STATS,
    ...
&#125;

需要知道,枚举类是可以定义抽象方法的,枚举类里定义抽象方法时不能使用abstract关键字将枚举类定义成抽象类(因为系统自动会为它添加abstract关键字),但因为枚举类需要显式创建枚举值,而不是作为父类,所以定义每个枚举值时必须为抽象方法提供实现,否则将出现编译错误。

经过改造后的导出枚举类如下:

public enum Exportkey &#123;
    CONTENT_HISTORY_LIST &#123;
        @Override
        public CsvDataService create() &#123;
            return SpringUtils.getBean(HistoryContentCsvDataServiceImpl.class);
        &#125;
    &#125;,
    CONTENT_CAPACITY_STATS &#123;
        @Override
        public CsvDataService create() &#123;
            return SpringUtils.getBean(ContentCapacityStatsServiceImpl.class);
        &#125;
    &#125;,
    CONTENT_AMOUNT_STATS &#123;
        @Override
        public CsvDataService create() &#123;
            return SpringUtils.getBean(ContentAmountStatsServiceImpl.class);
        &#125;
    &#125;,
    PLAY_COUNT_CONTENT_STATS &#123;
        @Override
        public CsvDataService create() &#123;
            return SpringUtils.getBean(PlayCountContentStatsServiceImpl.class);
        &#125;
    &#125;,
    ...

    public abstract CsvDataService create();
&#125;

定义了一个抽象的create()方法,在每个枚举值中提供实现,这样我们原先的方法就不用switch了,变成了一行代码,如下:

private Collection<String[]> initData(ExportParam exportParam, Exportkey key) &#123;
        return key.create().initData(exportParam);
&#125;

   转载规则

本文不允许转载。
 上一篇
SpringBoot整合Mybatis SpringBoot整合Mybatis
SpringBoot集成Mybatis实战 mybatis是一款优秀的持久层框架,支持定制化SQL,存储过程和高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或
2019-03-17
下一篇 
如何自己实现一个LRU Cache 如何自己实现一个LRU Cache
如何自己实现一个LRU Cache LRU是Least Recently Used的缩写,即最近最少使用的淘汰,在内存有限的情况下,可以使用这种算法,保持内存中是最热的数据。 思路lru有两种实现方法,可以通过HashMap+双向链表的形
2019-01-21
  目录