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{@Overridepublic 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;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.context = applicationContext;}
}
  • 定义事件处理类工厂,用来生产各种事件处理对象

@Component
public class EventProcessFactory {@AutowiredSpringContextUtil 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. 消除switch/case语句,不破坏代码的封闭性,使程序结构更符合面向对象思想(二)

    在 "消除switch/case语句,不破坏代码的封闭性,使程序结构更符合面向对象思想(一)"中,我们曾讨论过维护一个消息管理器来记录不同消息和它对应的消息处理类. 但是,这种实现 ...

  2. 工厂模式之消除switch/case语句

    2019独角兽企业重金招聘Python工程师标准>>> 我们在平时的编码中,我们经常会遇到这样的情况: 使用过多的switch/case 或者 if else 语句,非常不爽,也违背 ...

  3. 稍加改进的Switch/Case扩展方法

    引言 鹤冲天的<c#扩展方法奇思妙用>系列给了我很多启示,其中的很多用法大大提升了代码编写效率,最近小研究了一下他提供的<c#扩展方法奇思妙用变态篇三:switch/case组扩展& ...

  4. 消除switch语句以获得更好的代码结构

    消除switch语句以获得更好的代码结构 代码演化1:纯switch function counter(state = 0, action) {switch (action.type) {case ' ...

  5. 在C++中对字符串std::string使用switch/case语句

    如果你使用C语音的string,也就是char *,是可以放在switch/case语句中的. 在C++中是不能对字符串string使用switch/case语句的,这里的string指的是std:: ...

  6. python中有没有switch_Python为什么没有switch/case语句?

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

  7. java break在switch_java中switch case语句需要加入break的原因解析

    java中switch case语句需要加入break的原因解析 java 中使用switch case语句需要加入break 做了具体的实例分析,及编译源码,在源码中分析应该如何使用,大家可以参考下 ...

  8. 将switch case转为条件驱动

    switch case是一种.net里面常用的条件分支语句,挺好用的:不过有些缺点: 1.在有包含大量条件和执行语句的时候代码结构会很乱. 2.不太符合面对对象的设计原则. 3.对于查询条件是否满足一 ...

  9. python中case的用法_python中Switch/Case实现的示例代码

    python 的 python中Switch/Case实现的示例代码 学习Python过程中,发现没有switch-case,过去写C习惯用Switch/Case语句,官方文档说通过if-elif实现 ...

最新文章

  1. 【机器学习】集成模型方法
  2. 用Python给你的女神带上口罩~
  3. 30岁+3笔钱+631黄金比例=成功
  4. Python panads数据处理二
  5. Spring2.5事务配置的5种方法
  6. windows下JDK版本之间的切换
  7. SpringBoot 一个依赖搞定 session 共享,没有比这更简单的方案了!
  8. 火山PC模拟鼠标操作
  9. Java求抛物线输入角度速度_知道初速度和抛物线的角度,怎么计算落点
  10. DW怎么把模板拽进html文件中,在Dreamweaver中如何使用模板
  11. Python使用APP Inventor网络微数据库TinyWebDB
  12. 获取ua(user Agent)
  13. 计算机ncre教材,ncre教材
  14. 网易CEO丁磊:手机网游是未来新趋势
  15. BilSTM 实体识别_NLP入门实体命名识别(NER)+BilstmCRF模型原理Pytorch代码详解——最全攻略...
  16. 爬虫做js逆向分析的思路
  17. 基于html篮球网页游戏,分享一款在线打篮球游戏网页源码
  18. 用MATLAB画圣诞树的源代码
  19. nnDetection复现Luna16 附模型
  20. windows7现实计算机内存不足,win7电脑内存不足怎么解决

热门文章

  1. 连接mysql的机制_安装成功后mysql 8.0不能连接navicat的解决方法
  2. 不再迷惑,无值和 NULL 值
  3. roc曲线怎么绘制_利用ROC曲线寻找最佳cutoff值(连续型变量组成的riskscore)
  4. rabbitmq常用的五种模型
  5. cap流程图_3D流程图
  6. java中qq中拉伸的文件,delphi中如何实现QQ中的截图并实现拉伸放大移动的功能
  7. 软件测试性能测试结果,软件性能测试结果分析工具的研究与设计
  8. oracle通过sid远程登录,oracle怎么捕获用户登录信息,如SID,IP地址等
  9. 0xc000007b应用程序无法正常启动_应用程序无法正常启动0xc0000142
  10. 【CSDN】设置图片大小