Springboot消除switch

网友投稿 282 2022-12-25


Springboot消除switch

背景

最近,在使用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 CRSResponseVuynsFf();

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 setApplicationConthttp://ext(ApplicationContext applicationContext) throws BeansException {

this.context = applicationContext;

}

}

定义事件处理类工厂,用来生产各种事件处理对象

@Component

public class EventProcessFactory {

@Autowired

SpringContextUtil contextUtil;

private static Map eventProcessMap = new ConcurrentHashMap<>();

public EventProcessFactory() {

Map 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接口即可。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringCloud Eureka 服务注册实现过程
下一篇:Java 使用Calendar计算时间的示例代码
相关文章

 发表评论

暂时没有评论,来抢沙发吧~