介绍
当if-else或switch分支太多时,阿里规范要使用策略模式
定义一个算法接口,多个实现算法的具体类,将每个算法都封装起来,并且使它们之间可以互换。UML结构图如下:
Context是上下文,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用;Strategy是策略类,用于定义所有支持算法的公共接口;ConcreteStrategy是具体策略类,封装了具体的算法或行为,继承于Strategy。
举例
根据mq消息类型,分别处理
策略接口
public interface ConsumeStrategy {
/**
* 消费消息
* @author lipo
* @date 2019-10-15 17:17
* @param
* @return
**/
String consume(String msg);
}
策略实现类
标签处理
@StrategyType(MqTypeEnum.LABEL)
public class LabelConsumeStrategyImpl implements ConsumeStrategy {
/**
* @desc 消费标签消息
* @author lipo
* @date 2019-10-15 17:19
* @param
* @return
**/
@Override
public String consume(String msg) {
System.out.println(msg + ", 标签添加成功");
return "ok";
}
}
订单处理
@StrategyType(MqTypeEnum.ORDER)
public class OrderConsumeStrategyImpl implements ConsumeStrategy {
/**
* @desc 消费标签消息
* @author lipo
* @date 2019-10-15 17:19
* @param
* @return
**/
@Override
public String consume(String msg) {
System.out.println(msg + ", 订单添加成功");
return "ok";
}
}
上下文切换
@Component
public class ConsumeStrategyBuilder {
/**
* 转发map
*/
private static Map<MqTypeEnum, ConsumeStrategy> map = new ConcurrentHashMap<>();
//初始化转发map
static {
initDispatchMap();
}
/**
* 转发消费消息
* @param mqTypeEnum
* @param msg
* @return
*/
public String consume(MqTypeEnum mqTypeEnum, String msg) {
ConsumeStrategy consumeStrategy = map.get(mqTypeEnum);
return consumeStrategy.consume(msg);
}
/**
* 解析所有策略实现类,装载进入map中
*/
private static void initDispatchMap() {
List<String> list = PackageUtil.resolveAllClass(ConsumeStrategyBuilder.class.getPackage().getName() + ".impl");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (!CollectionUtils.isEmpty(list)) {
for (String classFullName :
list) {
try {
Class<?> aClass = classLoader.loadClass(classFullName);
StrategyType annotation = aClass.getAnnotation(StrategyType.class);
Object o = aClass.newInstance();
if (o instanceof ConsumeStrategy && annotation != null) {
map.put(annotation.value(), (ConsumeStrategy)o);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
测试
@RestController
@RequestMapping("design")
public class DesignController {
@Autowired
private ConsumeStrategyBuilder consumeStrategyBuilder;
/**
* http://localhost:8080/design/strategy?code=1&msg=hehe
* 策略模式
* @param code
* @param msg
* @return
*/
@GetMapping("strategy")
public String strategy(Byte code, String msg) {
MqTypeEnum mqTypeEnum = MqTypeEnum.getEnumByCode(code);
return consumeStrategyBuilder.consume(mqTypeEnum, msg);
}
}
项目https://github.com/mingwulipo/design-method.git