需求背景
1、在管控流程中,涉及到的业务操作很多,不同的业务具有不同的策略实现
举个具体的例子:
在比价管控流程中,有比价策略和管控策略,每个业务的比价和管控均不一样。因此使用策略模式来开发
整体架构流程
1、定义业务策略枚举: 比价 和 管控
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-17 16:33
**/
public enum StrategyType {
priceCompare,
priceControl
;
}
2、定义业务策略注解,标注出 策略的类
java
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-17 16:34
**/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
@Component
@Inherited
public @interface StrategyAnnotation {
/**
* 策略类型
*/
StrategyType[] strategyType();
/**
* 具体的策略建
*/
String[] dataType() default {};
}
3、定义策略基本方法
java
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-17 16:46
**/
public interface PriceCompareStrategy {
/**
* 执行价格比价
*/
public String doPriceCompare();
}
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-17 16:52
**/
public interface PriceControlStrategy {
/**
* 执行管控
* @return
*/
public String doPriceControl();
}
4、写每个具体实现的策略类
java
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-17 16:44
**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceCompare, dataType = "firstPriceCompare")
public class FirstPriceCompareStrategy implements PriceCompareStrategy {
@Override
public String doPriceCompare() {
System.out.println("-------first price compare start---------");
System.out.println("-------do do do ---------");
System.out.println("-------first price compare end---------");
return "first price compare end";
}
}
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-17 16:50
**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceCompare, dataType = "secondPriceCompare")
public class SecondPriceCompareStrategy implements PriceCompareStrategy {
@Override
public String doPriceCompare() {
System.out.println("-------second price compare start---------");
System.out.println("-------do do do ---------");
System.out.println("-------second price compare end---------");
return "second price compare end";
}
}
java
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-17 16:53
**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceControl, dataType = "firstPriceControl")
public class FirstPriceControlStrategy implements PriceControlStrategy {
@Override
public String doPriceControl() {
System.out.println("---------do first price control start ---------------");
System.out.println("---------do first price control end ---------------");
return "do first price control end";
}
}
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-17 16:53
**/
@Service
@StrategyAnnotation(strategyType = StrategyType.priceControl, dataType = "secondPriceControl")
public class SecondPriceControlStrategy implements PriceControlStrategy {
@Override
public String doPriceControl() {
System.out.println("---------do second price control start ---------------");
System.out.println("---------do second price control end ---------------");
return "do second price control start";
}
}
@Service
@StrategyAnnotation(strategyType = {StrategyType.priceCompare, StrategyType.priceControl}, dataType = "commonStrategy")
public class PriceCompareAndControlStrategy implements PriceCompareStrategy, PriceControlStrategy {
@Override
public String doPriceCompare() {
System.out.println("-------common price compare start---------------");
System.out.println("-------common price compare end---------------");
return "common price compare end";
}
@Override
public String doPriceControl() {
System.out.println("-------common price control start---------------");
System.out.println("-------common price control end---------------");
return "common price control end";
}
}
5、编写策略管理类,管理所有的策略,并且对外暴露出 拿到具体策略类的方法
java
package com.dgut.strategy.springboot_strategy;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Map;
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-17 16:59
**/
@Service
public class StrategyServiceManager {
@Autowired
private ApplicationContext context;
/**
* 存储策略:类型:具体实现类
*/
private Map<StrategyType, Map<String, Object>> map;
public <E> E getStrategyInstance(StrategyType strategyType, String type, Class<E> eClass) {
Map<String, Object> strategyTypeMap = map.get(strategyType);
if (strategyTypeMap != null && !map.isEmpty()) {
Object bean = strategyTypeMap.get(type);
if (bean != null) {
return eClass.cast(bean);
}
}
return null;
}
@PostConstruct
private void init() {
map = Maps.newHashMap();
Map<String, Object> beans = context.getBeansWithAnnotation(StrategyAnnotation.class);
for (Object value : beans.values()) {
StrategyAnnotation annotation = value.getClass().getAnnotation(StrategyAnnotation.class);
StrategyType[] strategyTypes = annotation.strategyType();
String[] dataTypes = annotation.dataType();
if (strategyTypes == null || strategyTypes.length == 0 || dataTypes == null || dataTypes.length == 0) {
throw new RuntimeException("注解上必填字段不能为空");
}
for (StrategyType strategyType : strategyTypes) {
for (String dataType : dataTypes) {
map.computeIfAbsent(strategyType, k -> Maps.newHashMap()).put(dataType, value);
}
}
}
}
}
6、代码流程测试
java
package com.dgut.strategy.springboot_strategy;
import com.dgut.strategy.springboot_strategy.compare.PriceCompareStrategy;
import com.dgut.strategy.springboot_strategy.control.PriceControlStrategy;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-07-18 16:17
**/
@SpringBootTest
public class StrategyTest {
@Autowired
private StrategyServiceManager strategyServiceManager;
@Test
public void test2() {
String strategyName = "priceControl";
String dataType = "firstPriceControl";
System.out.println(priceControlTest(strategyName, dataType));
String dataType2 = "secondPriceControl";
System.out.println(priceControlTest(strategyName, dataType2));
String dataType3 = "commonStrategy";
System.out.println(priceControlTest(strategyName, dataType3));
}
public String priceControlTest(String strategyName, String dataType) {
StrategyType strategyType = StrategyType.valueOf(strategyName);
if (strategyType == null) {
return "管控策略不存在";
}
PriceControlStrategy strategyInstance = strategyServiceManager
.getStrategyInstance(strategyType, dataType, PriceControlStrategy.class);
if (strategyInstance == null) {
return "找不到管控策略";
}
return strategyInstance.doPriceControl();
}
@Test
public void test() {
String strategyName = "priceCompare";
String dataType = "firstPriceCompare";
System.out.println(priceCompareTest(strategyName, dataType));
String dataType2 = "secondPriceCompare";
System.out.println(priceCompareTest(strategyName, dataType2));
String dataType3 = "commonStrategy";
System.out.println(priceCompareTest(strategyName, dataType3));
}
public String priceCompareTest(String strategyName, String dataType) {
StrategyType strategyType = StrategyType.valueOf(strategyName);
if (strategyType == null) {
return "策略不存在";
}
PriceCompareStrategy strategyInstance = strategyServiceManager
.getStrategyInstance(strategyType, dataType, PriceCompareStrategy.class);
if (strategyInstance == null) {
return "找不到比价策略";
}
return strategyInstance.doPriceCompare();
}
}
技术细节
通过spring的context对象,解析获取类注解,拿到bean,常规操作,这个要学起来,很多地方可以这样子操作呢。
总结
知道的越多,不知道的越多,希望对你有帮助! \color{red}知道的越多,不知道的越多,希望对你有帮助! 知道的越多,不知道的越多,希望对你有帮助!