文档章节

工作小记——switch-case改造

老虎是个蛋蛋
 老虎是个蛋蛋
发布于 2018/12/28 18:34
字数 1041
阅读 20
收藏 0

你是否也和我一样遇到过这个问题,因为判断类型特别多,以至于使用switch-case来进行判断,导致代码中写了一堆case判断,每当添加新的类型时,还需要在switch中添加新的case,导致代码维护越来越差,而且很不美观,扩展性也随之变差!!!! 下面我的改造或许会给你一些启发吧!!

最近在开发新项目中遇到一个问题,有8中类型,每种类型会执行不同的方法,导致代码中写了8个case做判断,虽然感觉阅读性可能会好一些,但是这堆case写在核心代码中“不!好!看!!!”,于是决定改造它!! 先看一下改造前核心代码的样子

for (int i = 0; i < list.size(); i++) {
                String performAction = list.get(i).getPerformAction();
                LOGGER.info("performAction orderId:{},performAction:{}",msg.getOrderId(),performAction);

                //此处状态对应PerformActionEnum中枚举值
                switch(Integer.parseInt(performAction)){
                    case 1://重推订单

                        break;
                    case 2://重推支付单

                        break;
                    case 3://重推运单

                        break;
                    case 4://重推服务商或者生成捞单报文

                        break;
                    case 5://邮件通知采销

                        break;
                    case 6://先删除订单再重推订单

                        break;
                    case 7://清关失败
                        customsClearanceFailed(msg);//置清关失败
                        addLog(list.get(i),msg);//添加日志
                        break;
                    default:
                        LOGGER.error("performAction 枚举值无效 msg:{}",msg.toString());
                        break;
                }
            }

再看一下改造后的核心代码

 for (int i = 0; i < list.size(); i++) {
 		String performAction = list.get(i).getPerformAction();
        LOGGER.info("performAction orderId:{},performAction:{}",msg.getOrderId(),performAction);
        //此处状态对应PerformActionEnum中枚举值
        IntelligentAssistantActionEnum serviceEnum = IntelligentAssistantActionEnum.getValue(performAction);
        String serviceName = serviceEnum.getServiceName();
        actionHandleService.handle(serviceName,list.get(i),msg);
 }

是不是简单了好多,下面介绍一下改造过程

将类型抽离出来,写成枚举

/**
 * action为执行动作的值
 * serviceName为具体执行方法使用到的service
 * Created by wang_xin on 17-7-14.
 */
public enum IntelligentAssistantActionEnum {
    CUSTOMS_CLEARANCE_FAILED(PerformActionEnum.CUSTOMS_CLEARANCE_FAILED.getId(), ActionServiceConstants.CUSTOMS_CLEARANCE_FAILED),
    CUSTOMS_CLEARANCE_FAILED_AND_CANCEL_ORDER(PerformActionEnum.CUSTOMS_CLEARANCE_FAILED_AND_CANCEL_ORDER.getId(), ActionServiceConstants.CUSTOMS_CLEARANCE_FAILED_AND_CANCEL_ORDER);

    private String action;
    private String serviceName;

    IntelligentAssistantActionEnum(String action, String serviceName) {
        this.action = action;
        this.serviceName = serviceName;
    }

    public String getAction() {
        return action;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public String getServiceName() {
        return serviceName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

    public static IntelligentAssistantActionEnum getValue(String action){
        for(IntelligentAssistantActionEnum etse : IntelligentAssistantActionEnum.values()){
            if(etse.getAction().equals(action)){
                return etse;
            }
        }
        return null;
    }
}

ActionServiceConstants为Service的名字,稍后会讲到如何使用这个静态变量,内容如下

public class ActionServiceConstants {
    public static final String CUSTOMS_CLEARANCE_FAILED="CUSTOMS_CLEARANCE_FAILED";
    public static final String CUSTOMS_CLEARANCE_FAILED_AND_CANCEL_ORDER="CUSTOMS_CLEARANCE_FAILED_AND_CANCEL_ORDER";
}

核心代码中大家可能注意到actionHandleService.handle(serviceName,list.get(i),msg);这个方法,下面介绍一下这个方法,首先定义ActionHandleService接口

public interface ActionHandleService {
    Object handle(String serviceName, IntelligentAssistantTo to, IntelligentAssistantMessage msg) throws Exception;
}

接着是实现类

public class ActionHandleServiceImpl implements ActionHandleService{
    private static final Logger LOGGER = LoggerFactory.getLogger(ActionHandleServiceImpl.class);
    @Override
    public Object handle(String serviceName, IntelligentAssistantTo to, IntelligentAssistantMessage msg) throws Exception{
        LOGGER.info("ActionHandleServiceImpl.handle orderId:{},serviceName:{},to:{},msg:{}",msg.getOrderId(),serviceName,to.toString(),msg.toString());
        try {
            Object handleService = SpringContextUtil.getBean(serviceName);
            if(handleService instanceof ActionInterface){
                return ((ActionInterface) handleService).handle(to,msg);
            }else {
                LOGGER.error("ActionHandleServiceImpl.handle service is error orderId:{},serviceName:{}",msg.getOrderId(),serviceName);
                throw new Exception("ActionHandleServiceImpl handle serviceError[serviceName="+serviceName+"]");
            }
        }catch (Exception e){
            LOGGER.error("ActionHandleServiceImpl.handle system error orderId:{},serviceName:{}",msg.getOrderId(),serviceName);
            throw new Exception("ActionHandleServiceImpl handle ERROR [serviceName="+serviceName+"]");
        }
    }
}

这个接口是我改造的核心方法,此方法可以根据传入的serviceName找到Spring托管下的对应service,此处的serviceName即为枚举对应的serviceName,那么每个service是如何写的呢,下面以其中一个service为例。 首先,需要定义接口,所有的类型service都要实现这个接口

public interface ActionInterface {
    public Object handle(IntelligentAssistantTo to,IntelligentAssistantMessage msg);
}

以case7为列,7这种类型首先需要创建一个ActionInterface的实现类

@Service(ActionServiceConstants.CUSTOMS_CLEARANCE_FAILED)
public class ClearanceFailedActionServiceImpl implements ActionInterface{
    private static final Logger LOGGER = LoggerFactory.getLogger(ClearanceFailedActionServiceImpl.class);
    @Resource
    private ClearanceMqService clearanceMqService;
    @Resource
    private IntelligentAssistantLogService intelligentAssistantLogService;

    @Override
    public Object handle(IntelligentAssistantTo to, IntelligentAssistantMessage msg) {
        LOGGER.info("ClearanceFailedActionServiceImpl.handle orderId:{},to:{},msg:{}",msg.getOrderId(),to.toString(),msg.toString());
        ClearanceMqService.MqNotifyTypeEnum emu = getEnumByErrorCode(to,msg);
        customsClearanceFailed(msg,emu);//置清关失败
        addLog(to,msg);//添加日志
        return true;
    }
}

大家不难看出,@Service注解中使用的是之前定义好的静态变量

至此改造完成,如果有新的类型该如何做呢?

  1. 在ActionServiceConstants中添加serviceName
  2. 在IntelligentAssistantActionEnum中添加枚举值
  3. 创建一个实现ActionInterface接口的service,@Service(ActionServiceConstants.新定义的变量)
  4. 在service中编写自己的逻辑

© 著作权归作者所有

老虎是个蛋蛋
粉丝 173
博文 31
码字总数 40085
作品 0
朝阳
高级程序员
私信 提问
讨论C语言常规优化策略——条件语句优化

C语言常规优化策略 2 条件语句优化 2.1 多分枝条件语句优化 多分枝条件语句一般采用switch语句,这样的程序无论从清晰性和效率上都比原来的程序要好。例如下面的函数采用三种函数形式分别计算...

abcMx
2013/04/24
106
0
PHP 03 选择结构

◆关系运算符 关系运算符是用来比较两个值得关系返回 true 或 false 运算后返回结果为 布尔类型 如: $b1=1>2; echo $b1;//false() $b2=1 ! =(2 + 1); echo $b2;//true(1) ◆逻辑运算符 逻辑...

Annie可馨
2016/11/05
6
0
[翻译] effective go 之 Control structures

Control structures The control structures of Go are related to those of C but differ in important ways. There is no do or while loop, only a slightly generalized for; switch is ......

pengfei_xue
2013/02/05
144
0
启航 —— 记 —— 第一次自考的启示:自考与自我改造

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Alexshi5/article/details/84076079 主干:启航 —— 记:一名初中学历Java程序员的自考本科之路 人类通过劳动...

_云卷云舒_
2018/11/18
0
0
Swift讲解专题六——流程控制

Swift讲解专题六——流程控制 一、引言 一种编程语言的强大与否,很大程度上取决于其提供的程序流程控制方案,就如使用汇编语言实现复杂的程序流程是一件痛苦的事情。Swift中提供了许多强大的...

珲少
2016/05/12
388
0

没有更多内容

加载失败,请刷新页面

加载更多

用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
3
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
12
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
13
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
6
0
Django的ChoiceField和MultipleChoiceField错误提示,选择一个有效的选项

在表单验证时提示错误:选择一个有效的选项 例如有这样一个表单: class ProductForm(Form): category = fields.MultipleChoiceField( widget=widgets.SelectMultiple(), ...

编程老陆
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部