Spring项目整合策略模式~实战应用

需求背景

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}知道的越多,不知道的越多,希望对你有帮助! 知道的越多,不知道的越多,希望对你有帮助!

相关推荐
rgeshfgreh15 小时前
C++模板与ABI:深度解析参数传递
策略模式
FreeBuf_2 天前
新型TCC绕过漏洞:macOS面临自动化攻击风险
macos·自动化·策略模式
JavaBoy_XJ3 天前
行为型-策略模式
策略模式
崎岖Qiu7 天前
【设计模式笔记24】:JDK源码分析-Comparator中的「策略模式」
java·笔记·设计模式·jdk·策略模式
辣机小司9 天前
【踩坑记录:EasyExcel 生产级实战:策略模式重构与防御性导入导出校验指南(实用工具类分享)】
java·spring boot·后端·重构·excel·策略模式·easyexcel
山风wind10 天前
设计模式-策略模式详解
设计模式·策略模式
“抚琴”的人11 天前
C#上位机策略模式
开发语言·c#·策略模式
梦里小白龙11 天前
JAVA 策略模式+工厂模式
java·开发语言·策略模式
秋邱13 天前
Java面向对象进阶实战:用工厂模式+策略模式优化支付系统
java·bash·策略模式