SpringBoot + 策略模式
下面是一个简单的实现demo:
首先是我们定义一个接口即起路由作用,我们具体的不同业务实现类来实现这个接口就可以;不同的业务分支我就使用加减乘除来代替
package com.example.bootdemo.operate; import org.springframework.stereotype.Component; public interface CalculationStrategy { /** * 策略接口 */ int operate(int num1, int num2); } @Component("add") class AddCalculationStrategyImpl implements CalculationStrategy { @Override public int operate(int num1, int num2) { return num1 + num2; } } @Component("div") class DivisionStrategyImpl implements CalculationStrategy { @Override public int operate(int num1, int num2) { return num1 / num2; } } @Component("mul") class MultiplicationStrategyImpl implements CalculationStrategy { @Override public int operate(int num1, int num2) { return num1 * num2; } } @Component("sub") class SubtractionStrategyImpl implements CalculationStrategy { @Override public int operate(int num1, int num2) { return num1 - num2; } } /** * 如果Component注解中不写标识会默认加载驼峰类名:testStrategyImpl */ @Component class TestStrategyImpl implements CalculationStrategy { @Override public int operate(int num1, int num2) { return num1 - num2; } }
第二步便是我们的策略上下文,我将其理解为策略工厂,这也是最核心的一个类;
这里我们项目启动的时候,第一步是初始化所有加了@component等类,我们的策略工厂的构造函数中有获取所有实现了路由规则的实现类名称,第二步便是将获取到的实现类名称放入到我们初始化的一个空的map中
package com.example.bootdemo.operate; import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Component public class CalculationFactory{ /** * 把策略角色(类型)key,和参数value放到Map中 * key就是beanName(具体策略实现类中@Component的名字),value就是接口(具体的实现类) * 实则是静态的创建了一个HashMap的对象,Maps可以根据key去获取value对象 */ public final Map<String, CalculationStrategy> calculationStrategyMap = new ConcurrentHashMap<>(4); /** * 利用构造函数在项目启动的时候将策略实现类注册到 map里 * @param strategyMap */ public CalculationFactory(Map<String, CalculationStrategy> strategyMap) { this.calculationStrategyMap.clear(); this.calculationStrategyMap.putAll(strategyMap); } //可以使用@Getter注解代替,这样写方便读者理解在Service层调用Context执行策略 public Map<String, CalculationStrategy> getCalculationStrategyMap() { return calculationStrategyMap; } }
第三步便是我们的路由接口实现,这一步便是具体路由的规则判断了 这里有一步我们需要对代码进行健壮性判断,以防map.get()结果为空导致系统报错,这里大家可以根据业务情况自行去处理。
package com.example.bootdemo.operate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class CalculationService { @Autowired private CalculationFactory calculationFactory; public int operateByStrategy(String strategy, int num1, int num2) { // 获取入参,根据不同的参数类型去执行不同的策略,Context的get方法是在这个地方用到的,operate方法就是一开始定义的策略接口 CalculationStrategy calculationStrategy = calculationFactory.getCalculationStrategyMap().get(strategy); if (calculationStrategy != null) { return calculationStrategy.operate(num1, num2); }else { return -1000; } } }
测试接口
package com.example.bootdemo.operate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/strategy") public class StrategyController { @Autowired private CalculationService calculationService; @GetMapping("/test/{operation}/{num1}/{num2}") public int testCalculation(@PathVariable String operation, @PathVariable int num1, @PathVariable int num2) { // 省略参数判空 return calculationService.operateByStrategy(operation, num1, num2); } }
本文来自博客园,作者:黄橙,转载请注明原文链接:https://www.cnblogs.com/RedOrange/p/19141547

浙公网安备 33010602011771号