Springboot消除switch-case方法
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方法的更多相关文章
- Java代码消除switch/case,if/else语句的几种实现方式
转自:https://my.oschina.net/stefanzhlg/blog/372413 我们在平时的编码中,我们经常会遇到这样的情况: 使用过多的switch/case 或者 if else ...
- 消除Switch...Case的过程
http://www.cnblogs.com/happyframework/p/3300170.html 目录 备注需求第一遍代码(重复的代码)第二遍代码(消除重复)备注 备注返回目录 不要重复自己, ...
- 设计原则:消除Switch...Case的过程,可能有点过度设计了。
备注 不要重复自己,也不要重复别人,一旦养成了“拷贝和粘贴”的习惯,写程序的时候非常容易导致重复,好在一直暗示自己要稍后进行重构,本文给出一个重构的示例. 需求 需求:按照年.月和日显示销售数据,根据 ...
- switch...case和if...else if的判断应用
判断成绩所属等级的 两种方法 1... switch...case方法: #include<stdio.h> int main(void) { ;i <= ;++i) // ...
- C语言中switch case语句可变参实现方法(case 参数 空格...空格 参数 :)
正常情况下,switch case语句是这么写的: : : ... ;break ; default : ... ;break ; } 接下来说一种不常见的,但是对于多参数有很大的帮助的写法: 先给一 ...
- Android Studio快捷键switch case 轻松转换为if else
Android Studio快捷键switch case 轻松转换为if else 今天碰到的问题,没有找到资料,后面找到了方法,这个记下来,转载请注明出处:http://www.cnblogs.co ...
- if语句,if...else if语句和switch...case语句的区别和分析
前段时间在工作中遇到了一个关于条件判断语句的问题,在if语句,if else if语句和switch case语句这三者之间分析,使用其中最有效率的一种方法. 所以就将这个问题作为自己第一篇博客的主要 ...
- Python | 基础系列 · Python为什么没有switch/case语句?
与我之前使用的所有语言都不同,Python没有switch/case语句.为了达到这种分支语句的效果,一般方法是使用字典映射: def numbers_to_strings(argument): sw ...
- switch使用方法之一周食谱例
/* Name:switch使用方法之一周食谱例 Copyright: By.不懂网络 Author: Yangbin Date:2014年2月17日 03:52:53 Description: */ ...
随机推荐
- Kata Container 介绍
docker容器,性能高,不安全:VM虚拟机,安全性好,性能损耗大:Kata Container轻量级虚拟机的容器,即安全,性能也高. 开源容器项目Kata Containers,旨在将虚拟机(VM) ...
- bzoj2306 [Ctsc2011]幸福路径 倍增 Floyd
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2306 题解 倍增 Floyd. 令 \(f[i][j][k]\) 表示走了 \(2^i\) 步 ...
- Knative 实战:基于 Knative Serverless 技术实现天气服务
提到天气预报服务,我们第一反应是很简单的一个服务啊,目前网上有大把的天气预报 API 可以直接使用,有必要去使用 Knative 搞一套吗?杀鸡用牛刀?先不要着急,我们先看一下实际的几个场景需求: 场 ...
- spring boot构建
1.新建Maven工程 1.File-->new-->project-->maven project 2.webapp 3.工程名称 k3 2.Maven 三个常用命令 选 项目右击 ...
- java中 运算符
我们先讨论 &,&&,| ,|| 这四个运算符 boolean a=true; boolean b=true; boolean c=false; //输出:a为true,b ...
- NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...
- Shiro学习资料
这篇博客的作者是张开涛,他写了很多专题文章,值得关注一下. 博客专栏 - 跟我学Shirohttp://www.iteye.com/blogs/subjects/shiro
- Flask学习 3 url_for的使用
#!/usr/bin/env python # encoding: utf-8 """ @version: v1.0 @author: cxa @file: flask0 ...
- drawRect
1) 画笔设置 Paint.Style.STROKE 中空模式 paint = new Paint(); //新建一个画笔对象 paint.setAntiAlias(true);//抗锯齿功能 pai ...
- SSL异常javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
jdk 7 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html jdk 8 http: ...