目录
- 需求:用户进行支付
- 1.目前支持支付宝支付和微信支付,未来会新增银行卡,余额等方式。使用策略模式,每一种支付方式都是一种策略。
- 2.根据用户传入的支付类型,创建不同的策略类,使用工厂模式。
- 3.封装一个facade的jar包,其他系统直接通过一个统一的入口,进行该功能的调用,使用门面模式。
1.新建策略类
@Service
public interface PayStrategy {
Boolean pay(Paybody paybody);
}
public class WxPayStrategy implements PayStrategy {
@Override
public Boolean pay(Paybody paybody) {
// 模拟微信支付过程
System.out.println("微信支付失败!");
return false;
}
}
public class ZfbPayStrategyPay implements PayStrategy{
@Override
public Boolean pay(Paybody paybody) {
// 模拟支付宝支付过程
System.out.println("支付宝支付成功!");
return true;
}
}
@Data
public class Paybody {
/**
* 支付类型
* ZFB 支付宝
* WX 微信
*/
private String type;
/**
* 商品
*/
private String product;
}
2.创建策略工厂
/**
* 支付策略工厂
*/
public class StrategyFactory {
public static PayStrategy getPayStrategy(String type){
// 1.通过枚举中的type获取对应value
String value = EnumUtil.getFieldBy(PayStrategyEnum::getValue, PayStrategyEnum::getType, type);
// 2.使用反射创建对应的策略类
PayStrategy payStrategy = ReflectUtil.newInstance(value);
return payStrategy;
}
}
/**
* 支付策略枚举
*/
public enum PayStrategyEnum {
ZFB("ZFB","com.example.demo.pay.stragety.ZfbPayStrategyPay"),
WX("WX","com.example.demo.pay.stragety.WxPayStrategy")
;
String type;
String value;
PayStrategyEnum(String type,String value){
this.type = type;
this.value = value;
}
public String getValue() {
return value;
}
public String getType() {
return type;
}
}
3.创建策略的上下文角色
起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
public class PayContext {
private PayStrategy payStrategy;
public PayContext(PayStrategy payStrategy) {
this.payStrategy = payStrategy;
}
public Boolean execute(Paybody paybody) {
return this.payStrategy.pay(paybody);
}
}
4.提供统一的访问入口
public class StrategyFacade {
public static Boolean Pay(Paybody paybody){
// 1.获取策略对象
PayStrategy payStrategy = StrategyFactory.getPayStrategy(paybody.getType());
// 2.获取策略上下文
PayContext payContext = new PayContext(payStrategy);
// 3.进行扣款
return payContext.execute(paybody);
}
}
5.创建 Controller 层,进行调用
@RestController
public class PayController {
@Autowired
private PayService payService;
@PostMapping("/pay")
public Boolean pay(@RequestBody Paybody paybody){
return payService.Pay(paybody);
}
}
@Service
public class PayService {
public Boolean Pay(Paybody paybody){
if (!EnumUtil.contains(PayStrategyEnum.class, paybody.getType())) {
throw new IllegalArgumentException("不支持的支付方式!");
}
return StrategyFacade.Pay(paybody);
}
}