The basic logic is as follows:
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: }
After writing, you will find that as the events increase, this code will be very long, and the processing functions of each event are also concentrated in one class. Easy to maintain. Therefore, through search and learning, we found that we can use Springboot's annotation, strategy mode, and simple factory to eliminate switch-case.
Refactoring
Define structure
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; } }
Define an annotation
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface CRSEventAnnotation { CRSEvent value(); }
Definition Event processing interface
public interface EventProcess { CRSResponse execute(CRSRequest resquest); }
All time processing classes must implement this interface. Among them, execute is the event processing method
Write a specific time processing class
Next, write the event processing class one by one, give the following example:
@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; } }
Define SpringContext tool class
@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; } }
Define event processing class factory to produce various event processing objects
@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); } }
Calling code modification
CRSEvent crsEvent = CRSEvent.valueOf(crsRequest.getEvent()); EventProcess eventProcess = EventProcessFactory.createEventProcess(crsEvent); if (eventProcess != null){ return eventProcess.execute(crsRequest); } return null;
In this way, there is no switch-case in the code, and adding an event is also very simple. You only need to implement the EventProcess interface.
The above is the detailed content of How to eliminate switch-case in Springboot. For more information, please follow other related articles on the PHP Chinese website!