第一版策略模式应该这样玩(一)利用的是Reflections反射框架 + 注解方式 实现的策略模式,这种是必须引用外部框架Reflections包才能使用,如果不想引用,那有没有另外一种方式可以实现策略模式呢,答案肯定是有的咯。
实现思路
利用接口实现类 + Application 方式实现策略模式
1.创建支付的策略接口并实现它
/**
* @Description:支付的策略类
* @Auther:Cc
* @Data:2020/4/18 22:12
*/
public interface Strategy {
//支付类型
String type;
//支付
double pay(int totalMoney);
}
/**
* @Description:工商银行的支付
* @Auther:Cc
* @Data:2020/4/18 22:13
*/
@Service
public class ICBCStrategy implements Strategy {
@Override
public String name() {
return "ICBC";
}
/**
* 计算需要支付的金额
* @param totalMoney 总金额
* @return
*/
@Override
public double pay(int totalMoney) {
return totalMoney * 0.1;
}
}
/**
* @Description:建设银行的支付
* @Auther:Cc
* @Data:2020/4/18 22:13
*/
@Service
public class CCBStrategy implements Strategy {
@Override
public String name() {
return "CCBS";
}
/**
* 计算需要支付的金额
* @param totalMoney 总金额
* @return
*/
@Override
public double pay(int totalMoney) {
return totalMoney * 0.8;
}
}
2.创建Bean的工厂类。可以根据选择的不同通道,生成对应的银行支付对象
/**
* @Description:创建Bean的工厂类
* @Auther:Cc
* @Data:2020/4/18 22:25
*/
@Component
public class StrageFactory implements ApplicationContextAware{
@Autowired
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//存放所有Strategy接口的实现
private HashMap<String, Strategy> beanMap = new HashMap<>();
private Map<String, Strategy> getFixedGroup(){
if(!CollectionUtils.isEmpty(beanMap)){
return beanMap;
}
HashMap<String, Strategy> groupMap = new HashMap<>();
String[] beanNames = applicationContext.getBeanNamesForType(Strategy.class);
for (String beanName : beanNames) {
Strategy strategy = applicationContext.getBean(beanName, Strategy.class);
if(Strategy == null){
continue;
}
groupMap.put(strategy.name(), Strategy);
}
this.beanMap = groupMap;
return beanMap;
}
/**
* 根据选择的通道,生产对应银行对象
* @param channelId
* @return
*/
public Strategy getStrategyByChannelName(String channelName) throw Exception{
return getFixedGroup().get(channelName);
}
}
3.模拟测试
/**
* @Description:根据选择的银行,进行相应的折扣计算。
* @Auther:Cc
* @Data:2020/4/18 22:05
*/
@Controller
@RequestMapping("/pay")
public class PayController {
//注入支付的工厂对象
@Autowired
private StrageFactory strageFactory ;
/**
* 根据选择的银行,进行相应的折扣计算。
* @param request
* @return
*/
@RequestMapping("/calculate")
@ResponseBody
Object calculate(HttpServletRequest request){
String channelId = request.getParameter("channelId"); //选择的银行ID
String totalMoney = request.getParameter("totalMoney"); //总金额
//得到工厂对象
StrageFactory strageFactory = StrageFactory.getInstance();
//根据选择的银行,创建相对应的对象
Strategy strategy = strageFactory.getStrategyByChannelId(Integer.parseInt(channelId));
//策略模式进行支付
double payMoney = strageFactory.getStrategyByChannelName("ICBC").pay(Integer.parseInt(totalMoney));
return payMoney;
}
}
4.结果
结果与第一期验证结果一样,故不贴图