概念
接口提供抽象策略方法,由实现类提供具体的策略,并在使用时能整体替换。
- Strategy 策略接口
- ConcreteStrategy 具体策略实现类
- Context 上下文 用来选择具体策略
适用场景
- 根据不同业务类型选择不同的处理器来处理
- 替换大量if else
优点
- 策略之间可以随意切换
- 添加新策略只需要新建类,不需要修改原有代码
缺点
- 当策略比较多时,也需要较多的实现类
实战
根据不能消息类型来选择不能的消息处理器
- 消息实体类
@Data
public class Message {
private String type;
private String content;
}
- 消息处理接口 策略接口
public interface IMessageHandler {
/**
* 消息处理
* @param message msg
*/
void handle(Message message) throws Exception;
/**
* 支持处理的消息类型 text、image 等
* @return string
*/
String support();
}
- 纯文本消息处理器 具体策略
/**
* 纯文本消息处理器
* @author xup
* @date 2019/11/12 19:00
*/
@Component
public class TextMessageHandler implements IMessageHandler {
@Override
public void handle(Message message) {
System.out.println("处理纯文本消息");
}
@Override
public String support() {
return "Text";
}
}
- 图片消息处理器 具体策略
/**
* 图片消息处理器
* @author xup
* @date 2019/11/12 19:01
*/
@Component
public class ImageMessageHandler implements IMessageHandler {
@Override
public void handle(Message message) {
System.out.println("处理纯文本消息");
}
@Override
public String support() {
return "Image";
}
}
- 消息处理器路由类 策略路由类
/**
* 消息处理器路由类
* 只进行路由,不进行消息处理
* @author xup
* @date 2019/11/12 19:06
*/
@Order(1)
@Component
public class MessageHandlerRoute implements IMessageHandler{
/**
* 业务类型和业务处理器存放的容器
*/
private Map<String, IMessageHandler> messageHandlerMap = new HashMap<>(8);
/**
* 初始化类是 将IMessageHandler的所有实现类放入map容器
*/
@PostConstruct
public void init(){
Map<String, IMessageHandler> beanMap = SpringContextHolder.getBeansOfType(IMessageHandler.class);
for (IMessageHandler handler : beanMap.values()) {
messageHandlerMap.put(handler.support(), handler);
}
}
/**
* 根据消息类型路由到不同的处理器
* @param message msg
* @return IMessageHandler
*/
public IMessageHandler route(Message message) throws Exception {
IMessageHandler handler = messageHandlerMap.get(message.getType());
if (handler == null){
throw new Exception("此消息类型没有配置处理器");
}
return handler;
}
@Override
public void handle(Message message) throws Exception {
IMessageHandler handler = route(message);
handler.handle(message);
}
@Override
public String support() {
return "null";
}
}
路由类可不实现策略接口。 可通过注入路由类,然后路由到具体的处理器再进行处理
IMessageHandler handler = messageHandlerRoute.route(message)
handler.handle(message)
- spring 上下文持有类
/**
* spring 上下文持有类
*
* @author xup
* @date 2019/11/12 17:45
*/
@Component
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHolder.applicationContext = applicationContext;
}
/**
* 获取ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 从applicationContext中得到Bean, 自动转型为所赋值对象的类型.
*/
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName) {
return (T)applicationContext.getBean(beanName);
}
/**
* 获取spring 容器中所有指定类型的Bean
* @param type class
* @return map
*/
public static <T> Map<String, T> getBeansOfType(Class<T> type) {
return applicationContext.getBeansOfType(type);
}
}
- 实际调用
@Autowired
IMessageHandler messageHander;
messageHandler.hander(message);