策略模式在支付场景的使用
1、先看使用方式
RegistrationForm form = getByFormCode(payParam.getFormCode());
//挂号单不存在
if (form == null) {
return payTypeFactory.getType(RegistrationPayTypeEnum.APP_FIRST_PAY.getType()).pay(payParam);
}
//挂号单已存在
return payTypeFactory.getType(RegistrationPayTypeEnum.APP_REPEAT_PAY.getType()).pay(payParam);
2、实现思路
1)前端传来的报文中的Type类型
2)使用工厂类根据Type类型的值获得对应的策略实现类
3)执行相关方法
3、相关实现类
public enum PayTypeEnum {
APP_FIRST_PAY(1, "APP首次支付"),
APP_REPEAT_PAY(2, "APP二次支付"),
;
int type;
String desc;
public int getType() {
return type;
}
PayTypeEnum(int type, String desc) {
this.type = type;
this.desc = desc;
}
}
public interface PayType {
/**
* 获得支付类型
*
* @return 支付类型
*/
Integer getType();
/**
* 支付方法
*
* @param payParam
* @return
*/
PayVO pay(Order order);
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class PayTypeFactory implements InitializingBean, ApplicationContextAware {
private static final Map<Integer, PayType> PAY_TYPE_HANDLER_MAP = new HashMap<>();
private ApplicationContext appContext;
public PayType getType(Integer type) {
return PAY_TYPE_HANDLER_MAP.get(type);
}
@Override
public void afterPropertiesSet() throws Exception {
appContext.getBeansOfType(PayType.class)
.values()
.forEach(handler -> PAY_TYPE_HANDLER_MAP.put(handler.getType(), handler));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
appContext = applicationContext;
}
}
@Component
@Slf4j
public class AppFirstPay implements PayType {
@Autowired
OrderService orderService;
@Override
public Integer getType() {
return OrderPayTypeEnum.APP_FIRST_PAY.getType();
}
@Override
public PayVO pay(OrderPayParam payParam) {
Order order;
//订单不存在生成订单
order = orderService.assembleOrder(payParam);
//调用交易系统去支付
OrderPayVO payResult = orderService.payProcess(order, payParam);
return payResult;
}
}
@Component
@Slf4j
public class AppRepeatPay implements PayType {
@Autowired
OrderService orderService;
@Override
public Integer getType() {
return PayTypeEnum.APP_REPEAT_PAY.getType();
}
@Override
public PayVO pay(PayParam payParam) {
//订单已存在
Form order = orderService.getByFormCode(payParam.getFormCode());
//调用交易系统去支付
PayVO payResult = orderService.payProcess(order, payParam);
return payResult;
}
}