一、什么情况下使用策略模式
功能类似的业务功能,避免创建多个接口,大量if else 判断逻辑,简化代码
二、我以支付为例(支付方式有微信,支付宝支付)
1、新建策略抽象类或者接口
public interface ThirdPayStrategyService {
/**
* 第三方支付接口(微信 支付宝)
* @param order
* @param clientIp
* @return
*/
Map<String,String> pay(Orders order, String clientIp);
}
2、定义俩个实现类实现当前支付接口
wx支付实现类
@Service("wxPay")
@Slf4j
public class WxPayStrategyServiceImpl implements ThirdPayStrategyService {
@Override
public Map<String, String> pay(Orders order, String clientIp) {
Map<String,String> map=new HashMap<>();
map.put("success","true");
map.put("type","wxPay");
log.info("微信支付启动");
return map;
}
}
支付宝支付实现类
@Service("aliPay")
@Slf4j
public class AliPayStrategyServiceImpl implements ThirdPayStrategyService {
@Override
public Map<String, String> pay(Orders order, String clientIp) {
Map<String,String> map=new HashMap<>();
map.put("success","true");
map.put("type","aliPay");
log.info("支付宝支付启动");
return map;
}
}
3、定义执行策略类
@Component
@Slf4j
public class ThirdPayStrategyContext {
@Autowired
private final Map<String, ThirdPayStrategyService> payMap=new HashMap<>();
public Map<String,String> pullPay(Integer payType){
log.info("策略对象={}", payMap);
return payMap.get(PayTypeEnum.getPayTypeByCode(payType)).pay(new Orders(), "127.0.0.1");
}
}
俩种支付实现类对象会在spring的加载下自动注入到payMap中,map中key是service的名称 例如:@Service(“aliPay”)value 是对象的地址值
4、接口调用
@RestController
@RequestMapping("/test")
@Slf4j
public class WebController {
@Autowired
private ThirdPayStrategyContext thirdPayStrategyContext;
@GetMapping("/pay/{payType}")
public String payTest(@PathVariable Integer payType) {
Map<String, String> result = thirdPayStrategyContext.pullPay(payType);
log.info("调用支付返回结果={} 传参={}", JSON.toJSONString(result), payType);
return "success";
}
}
5、调用结果
附:枚举类
public enum PayTypeEnum {
WX_PAY(1,"wxPay"),
ALI_PAY(2,"aliPay");
private Integer code;
private String payType;
PayTypeEnum() {
}
PayTypeEnum(Integer code, String payType) {
this.code = code;
this.payType = payType;
}
public Integer getCode(){
return code;
}
public String getPayType(){
return payType;
}
public static String getPayTypeByCode(Integer code){
PayTypeEnum[] list = PayTypeEnum.values();
for (PayTypeEnum payTypeEnum : list) {
if(code.equals(payTypeEnum.code)){
return payTypeEnum.payType;
}
}
return null;
}
public static List<Integer> typeCodeList(){
ArrayList<Integer> codeList = Lists.newArrayList();
PayTypeEnum[] list = PayTypeEnum.values();
for (PayTypeEnum payTypeEnum : list) {
codeList.add(payTypeEnum.code);
}
return codeList;
}
}