当我们的业务逻辑根据不同的场景要做不同的处理时,需要大量的if判断加处理,这样导致代码臃肿且拓展性低;下面我用一个简单的业务,使用策略模式去处理不同的场景;业务场景为在IM聊天中,根据不同的消息类型,去处理不同的消息。
1.定义处理接口
public interface MessageHandler {
void handle(MsgContext param);
}
2.创建各业务实现handler
@Component
@MessageTypeAnnotation(MessageType.TEXT)
public class TextMessageHandler implements MessageHandler {
@Override
public void handle(MsgContext param) {
System.out.println("TextMessageHandler="+param.getMsg());
}
}
3.创建类型枚举
public enum MessageType {
TEXT,
VIDEO
}
4.创建自定义注解MessageTypeAnnotation
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MessageTypeAnnotation {
MessageType value() default MessageType.TEXT;
}
5.创建参数上下文对象
@Data
public class MsgContext {
private MessageType messageType;
private String msg;
}
6.创建消息handler工厂
@Component
public class MeaasgeFactory {
private Map<MessageType, MessageHandler> handlerMap = new ConcurrentHashMap<>();
@Autowired
public void init(Map<String, MessageHandler> handlerMaps) {
handlerMap.clear();
handlerMaps.keySet().stream().forEach(beanName -> {
Class<? extends MessageHandler> aClass = handlerMaps.get(beanName).getClass();
MessageTypeFlag annotation = aClass.getAnnotation(MessageTypeFlag.class);
if (annotation != null) {
handlerMap.put(annotation.value(), handlerMaps.get(beanName));
}
});
}
public MessageHandler getHandler(MessageType type) {
if (handlerMap == null) {
return null;
}
return handlerMap.get(type);
}
}
7.单元测试
@Resource
private MeaasgeFactory meaasgeFactory;
@GetMapping("/test")
public WebResponse<BrandRelationResult> test(MsgContext param) {
MsgContext msgContext = new MsgContext();
msgContext.setMessageType(MessageType.VIDEO);
msgContext.setMsg("我是文本");
MessageHandler handler = meaasgeFactory.getHandler(msgContext.getMessageType());
handler.handle(msgContext);
return null;
}