Springboot消除switch-case方法

背景

最近,在使用springboot开发一个接口的时候,需要根据接收的请求事件类型,去执行不同的操作,返回不同的结果,基本逻辑如下:

  String event = crsRequest.getEvent();
CRSResponse crsResponse = null;
switch (event) {
case CRSRequestEvent.APP_START:
crsResponse = processAppStartCommand(crsRequest);
break;
case CRSRequestEvent.INIT_COMPLETE:
crsResponse = processInitCompleteCommand(crsRequest);
break;
case CRSRequestEvent.COLLECT_COMPLETE:
crsResponse = processCollectCompleteCommand(crsRequest);
break;
case CRSRequestEvent.COLLECT_NO_INPUT:
crsResponse = processCollectNoInputCommand(crsRequest);
break;
case CRSRequestEvent.PLAY_COMPLETE:
crsResponse = processPlayCompleteCommand(crsRequest);
break;
default:
}

写完会发现,随着事件的增加,这段代码会很长,每个事件的处理函数也都集中在一个类当中,不好维护。因此,通过搜索学习发现,可以使用Springboot的注解+策略模式+简单工厂的方式来消除switch-case。

重构

  • 定义结构体
public enum CRSEvent {
APP_START("APP_START"),
INIT_COMPLETE("INIT_COMPLETE"),
PLAY_COMPLETE("PLAY_COMPLETE"),
COLLECT_COMPLETE("COLLECT_COMPLETE"),
COLLECT_NO_INPUT("COLLECT_NO_INPUT"),
APP_END("APP_END"),
RESP_ERROR_CMD("RESP_ERROR_CMD"); private String event; CRSEvent(String event){
this.event = event;
} public String getEvent() {
return event;
} public void setEvent(String event) {
this.event = event;
}
}
  • 定义一个注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CRSEventAnnotation { CRSEvent value();
}
  • 定义事件处理接口
public interface EventProcess {
CRSResponse execute(CRSRequest resquest);
}

所有的时间处理类都要实现这个接口。其中,execute是事件的处理方法

编写具体的时间处理类

接下来,逐个的编写事件处理类,举下面一个例子:

@Component("appStartProcess")
@CRSEventAnnotation(value = CRSEvent.APP_START)
public class AppStartProcess implements EventProcess{ @Override
public CRSResponse execute(CRSRequest resquest) {
CRSResponse response = new CRSResponse();
response.setCommand(CRSResponseCmd.IVR_SESSION_INIT);
CRSResponse.Message message = new CRSResponse.Message();
message.setTts_vid("65580");
message.setTts_speed("120");
response.setMessage(message);
return response;
}
}
  • 定义SpringContext工具类
@Component
public class SpringContextUtil implements ApplicationContextAware{ private ApplicationContext context; public ApplicationContext getContext(){
return context;
} @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}
  • 定义事件处理类工厂,用来生产各种事件处理对象
@Component
public class EventProcessFactory { @Autowired
SpringContextUtil contextUtil; private static Map<CRSEvent, EventProcess> eventProcessMap = new ConcurrentHashMap<>(); public EventProcessFactory() {
Map<String, Object> beanMap = contextUtil.getContext().getBeansWithAnnotation(CRSEventAnnotation.class); for (Object evetProcess : beanMap.values()) {
CRSEventAnnotation annotation = evetProcess.getClass().getAnnotation(CRSEventAnnotation.class);
eventProcessMap.put(annotation.value(), (EventProcess) evetProcess);
}
} public static EventProcess createEventProcess(CRSEvent event){
return eventProcessMap.get(event);
}
}
  • 调用代码修改
 CRSEvent crsEvent = CRSEvent.valueOf(crsRequest.getEvent());
EventProcess eventProcess = EventProcessFactory.createEventProcess(crsEvent);
if (eventProcess != null){
return eventProcess.execute(crsRequest);
}
return null;

这样,代码就没有了switch-case,增加一个事件也很简单,只需要实现EventProcess接口即可。

原博客

Springboot消除switch-case方法的更多相关文章

  1. Java代码消除switch/case,if/else语句的几种实现方式

    转自:https://my.oschina.net/stefanzhlg/blog/372413 我们在平时的编码中,我们经常会遇到这样的情况: 使用过多的switch/case 或者 if else ...

  2. 消除Switch...Case的过程

    http://www.cnblogs.com/happyframework/p/3300170.html 目录 备注需求第一遍代码(重复的代码)第二遍代码(消除重复)备注 备注返回目录 不要重复自己, ...

  3. 设计原则:消除Switch...Case的过程,可能有点过度设计了。

    备注 不要重复自己,也不要重复别人,一旦养成了“拷贝和粘贴”的习惯,写程序的时候非常容易导致重复,好在一直暗示自己要稍后进行重构,本文给出一个重构的示例. 需求 需求:按照年.月和日显示销售数据,根据 ...

  4. switch...case和if...else if的判断应用

    判断成绩所属等级的 两种方法 1...      switch...case方法: #include<stdio.h> int main(void) { ;i <= ;++i) // ...

  5. C语言中switch case语句可变参实现方法(case 参数 空格...空格 参数 :)

    正常情况下,switch case语句是这么写的: : : ... ;break ; default : ... ;break ; } 接下来说一种不常见的,但是对于多参数有很大的帮助的写法: 先给一 ...

  6. Android Studio快捷键switch case 轻松转换为if else

    Android Studio快捷键switch case 轻松转换为if else 今天碰到的问题,没有找到资料,后面找到了方法,这个记下来,转载请注明出处:http://www.cnblogs.co ...

  7. if语句,if...else if语句和switch...case语句的区别和分析

    前段时间在工作中遇到了一个关于条件判断语句的问题,在if语句,if else if语句和switch case语句这三者之间分析,使用其中最有效率的一种方法. 所以就将这个问题作为自己第一篇博客的主要 ...

  8. Python | 基础系列 · Python为什么没有switch/case语句?

    与我之前使用的所有语言都不同,Python没有switch/case语句.为了达到这种分支语句的效果,一般方法是使用字典映射: def numbers_to_strings(argument): sw ...

  9. switch使用方法之一周食谱例

    /* Name:switch使用方法之一周食谱例 Copyright: By.不懂网络 Author: Yangbin Date:2014年2月17日 03:52:53 Description: */ ...

随机推荐

  1. 消灭 Java 代码的“坏味道”

    消灭 Java 代码的“坏味道” 原创: 王超 阿里巴巴中间件 昨天 导读 明代王阳明先生在<传习录>谈为学之道时说: 私欲日生,如地上尘,一日不扫,便又有一层.着实用功,便见道无终穷,愈 ...

  2. PyCharm使用技巧总结

    PyCharm高频使用快捷键 快速修复:ALT + ENTER 搜索: 双击Shif 垂直分隔窗口: ALT + V 另起一行: SHIFT + ENTER 删除当前插入符所在的行: Ctrl + Y ...

  3. 13DBUtils工具类

    如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils. DBUtils就是JDBC的简化开发工具包.需要项 ...

  4. python 按多维列表中的某一个元素位进行排序

    import os,re top = os.popen("tasklist") process_list = [] split_r = r"\s+" memor ...

  5. Python操作cx_Oracle笔记

    参考文章: http://cx-oracle.readthedocs.io/en/latest/cursor.html # 创建数据库连接 ordb = Oracle.connect("{0 ...

  6. 026:if标签使用详解

    if标签使用详解: if 标签: if 标签相当于 Python 中的 if 语句,有 elif 和 else 相对应,但是所有的标签都需要用标签符号  {%  %}  进行包裹. if 标签中可以使 ...

  7. CSS基础知识总结二

    <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/html"> ...

  8. 容易混淆的JavaScript基础知识之语法部分

    type 属性: 默认的 type 就是 javascript, 所以不必显式指定 type 为 javascript javascript 不强制在每个语句结尾加 “:” , javascript ...

  9. Strassen __128int

    题目链接 题意思路很简单,递归求最小就好了.但__128int没见过.故写博客记下.__128int如果输入输出就要自己写函数. #include<bits/stdc++.h> using ...

  10. Milking Grid poj2185

    Milking Grid POJ - 2185 时限: 3000MS   内存: 65536KB   64位IO格式: %I64d & %I64u 提交 状态 已开启划词翻译 问题描述 Eve ...