近在做项目的时候,需要接入支付。由于接入第三方支付而且还不知止一家,需要接入很多家。比如说APP请求支付宝、微信、H5请求支付宝支付等。每家支付都一个回调。现如今的代码,根据不同的第三方支付一大堆else if判断。
策略模式:
用法:
• 针对同一类型的问题有多种处理方式,仅仅是具体行为有差别时。
• 需要安全地封装多种同一类型的操作时。
• 出现同一个抽象类有多个子类,而又需要使用if-else或switch-case来选择子类时。
步骤:
1.创建一个支付接口,提供两个方法
public interface PaymentService {
String pay(String type);
// 每家支付对应的类型
PayTypeEnum getPayType();
}
2.每个支付,都去实现该接口
@Service
public class AppAliPayServiceImPl implements PaymentService {
@Override
public String pay(String type) {
System.out.println("APP请求支付宝支付");
return "APP请求支付宝支付";
}
@Override
public PayTypeEnum getPayType() {
return PayTypeEnum.APPALIPAY;
}
}
3.然后准备一个工厂(工厂模式)
public final class PayFactory {
public PayFactory() {
}
public static Map<PayTypeEnum , PaymentService> PAYMAP = new ConcurrentHashMap<>();
static {
Map<String,PaymentService> beansOfType = ApplicationContextHelper.getBeansOfType(PaymentService.class);
for(Map.Entry<String,PaymentService> entry: beansOfType.entrySet()){
PaymentService paymentService = entry.getValue();
PAYMAP.put(paymentService.getPayType(), paymentService);
}
}
public static PaymentService getPay(PayTypeEnum payTypeEnum){
return PAYMAP.get(payTypeEnum);
}
}
spring获取Bean
@Component
public class ApplicationContextHelper implements ApplicationContextAware {
public static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {
return applicationContext.getBeansOfType(clazz);
}
}
4.新增一个枚举类转换方法
public enum PayTypeEnum {
WEIXIN, H5ALIPAY, APPALIPAY;
public static PayTypeEnum para(String type){
for(PayTypeEnum payTypeEnum:PayTypeEnum.values()){
if(type.equalsIgnoreCase(payTypeEnum.name())){
return payTypeEnum;
}
}
return null;
}
}
5.通过接口测试即可
@PostMapping("/pay")
public String pay() {
PayTypeEnum payType = PayTypeEnum.para("H5ALIPAY");
String result = PayFactory.getPay(payType).pay("1");
log.info("支付宝返回的信息是:" + result);
return result;
}
6.简单测试,用postman测试后,如下图所示:
到此,优化完毕。使用了工厂模式+策略模式+单列模式进行了优化这块的逻辑。
代码地址:https://github.com/virtuousOne/pay