需求
我们最近要开发一个多方支付,支持支付宝支付、微信支付、银联支付、等等的多方,以后说不准还有applePay、等等多种方式进行支付。一开始写if else确实没毛病,但是仔细一想,好像不符合我们设计模式的开闭原则,下面就来看看我们在spring环境中如何使用策略模式
流程
一般来说我们的api是从controller进来的,然后service,然后进行策略模式的选择,然后进到策略接口,然就是具体的实现方法的:
api—>service—>strategyContext—>Strategy—>strategyService
controller
@RestController
@RequestMapping("/strategy")
public class StrategyController {
@Autowired
private PaymentStrategyContext context;
@GetMapping("pay")
public String pay(@RequestParam("type") String type, @RequestParam("amount") double amount){
context.handle(type,amount);
return "支付成功";
}
}
context
@Component
@Slf4j
public class PaymentStrategyContext {
/**
* 策略集合
*/
@Autowired
private Map<String, PaymentStrategy> paymentStrategyMap = new HashMap<>();
private static Map<String, String> classStrategyMap = new HashMap<>();
static {
classStrategyMap.put("ylk", "unionPayStrategy");
classStrategyMap.put("wx", "weChatPayStrategy");
classStrategyMap.put("zfb", "aliPayStrategy");
}
public void handle(String type,double amount){
String className = classStrategyMap.get(type);
PaymentStrategy paymentStrategy = paymentStrategyMap.get(className);
if (paymentStrategy==null){
log.warn("找策略失败,没有这个策略:{}",paymentStrategy);
throw new RuntimeException("找策略失败,没有这个策略");
}
paymentStrategy.pay(amount);
}
}
策略接口(对扩展开放)
public interface PaymentStrategy {
// 支付
void pay(double amount);
// 或者其他业务...
}
具体实现类
@Service
public class AliPayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
// 调用支付宝支付接口
// ...
System.out.println("使用支付宝支付:" + amount + "元");
}
}
/**
* 银联卡支付策略
*/
@Service
public class UnionPayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
// 调用银联支付接口
// ...
System.out.println("使用银联支付:" + amount + "元");
}
}
/**
* 微信支付策略
*/
@Service
public class WeChatPayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
// 调用微信支付接口
// ...
System.out.println("使用微信支付:" + amount + "元");
}
}