当支付时可能会出现不同的支付方式,平时都是使用if...else...语句实现,这样存在着不好的地方就是没当有新的支付方式出现时需要新增if语句,使用策略模式可以避免这种情况。代码如下:
创建支付接口PayStrategy:
/**
* @Description: 支付接口
*/
public interface PayStrategy {
/**
* @Description:需要实现的支付方法
*/
String pay(String orderNo);
}
实现支付接口,使用支付宝支付:
/**
* @description: 阿里支付方式
**/
@Component
public class AlipayStrategy implements PayStrategy {
@Override
public String pay(String orderNo) {
System.out.println("阿里支付方式" + orderNo);
return "阿里支付方式:" + orderNo;
}
}
实现支付接口,使用微信支付:
/**
* @description: 微信支付渠道
**/
@Component
public class WeChatPayStrategy implements PayStrategy {
@Override
public String pay(String orderNo) {
System.out.println("微信支付渠道:" + orderNo);
return "微信支付渠道:" + orderNo;
}
}
以上两种支付方式已经注入到spring中,从spring中获取到相应的bean然后去执行对应bean的支付方法,代码如下:
/**
* @description: 策略模式上下文
**/
@Component
public class PayContext implements ApplicationContextAware {
private Map<String, PayStrategy> payContext;----------01
public Map<String, PayStrategy> getPayContext() {
return payContext;
}
/**
* @Description: 获取spring中实现了PayStrategy接口的实现类的bean,把它们注入到payContext属性中去
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, PayStrategy> beansOfType = applicationContext.getBeansOfType(PayStrategy.class);
payContext = new HashMap<>();
beansOfType.forEach((key, value) -> {
payContext.put(key, value);
});
}
/**
* @Description: 执行支付方法
* @Param: [payChannel支付方式, payNo支付金额]
* @return: void
*/
public void execpay(String payChannel, String payNo) {
PayStrategy payStrategy = payContext.get(payChannel);
String pay = payStrategy.pay(payNo);
}
}
01行代码中paycontext中的结构为<bean名称,bean实例对象>,后续代码通过bean名称即可获得对应bean实例对象,bean名称一般是类名首字母小写。
调用支付方式代码:
/**
* @description: 支付
**/
@Service
public class NewPayService {
@Autowired
private PayContext payContext;
public void pay(String payChannel,String payNo) {
payContext.execpay(payChannel, payNo);
}
}
开启测试类测试效果:
@Autowired
private NewPayService newPayService;
@Test
public void newPayService() {
newPayService.pay("alipayStrategy","123");
newPayService.pay("weChatPayStrategy","456");
}
运行代码,结果为:
阿里支付方式123
微信支付渠道:456
这种方式核心是获取到bean实例,在spring框架中获取到bean实例就可以对这个bean中的方法参数做各种操作了。获取spring中bean的方法可以参考(SpringBoot获取bean的几种方式_springboot 获取bean-CSDN博客)。
那么,除了spring还可以使用枚举来实现相同的作用:
支付接口为:
/**
* @Description: 支付接口
*/
public interface PayStrategy {
/**
* @Description:需要实现的支付方法
*/
String pay(String orderNo);
}
阿里支付实现:
/**
* @description: 阿里支付方式
**/
public class AlipayStrategy implements PayStrategy {
@Override
public String pay(String orderNo) {
System.out.println("阿里支付方式" + orderNo);
return "阿里支付方式:" + orderNo;
}
}
微信支付实现:
/**
* @description: 微信支付渠道
**/
public class WeChatPayStrategy implements PayStrategy {
@Override
public String pay(String orderNo) {
System.out.println("微信支付渠道:" + orderNo);
return "微信支付渠道:" + orderNo;
}
}
枚举类代码为:
public enum PayType {
ALI_PAY(new AlipayStrategy()),
WECHAT_PAY(new WeChatPayStrategy());
private PayStrategy payStrategy;
PayType(PayStrategy payStrategy) {
this.payStrategy = payStrategy;
}
public PayStrategy getPayStrategy() {
return this.payStrategy;
}
}
测试类测试代码:
@Test
public void newPayService() {
//模仿前端传入String字段为ALI_PAY表示选择用的支付方式
String s = "ALI_PAY";
//通过传入的String字段获取对应的支付方式
PayType payType = PayType.valueOf(s);
PayStrategy payStrategy = payType.getPayStrategy();
String pay = payStrategy.pay("123456");
}
执行测试代码后结果为
阿里支付方式123456
478

被折叠的 条评论
为什么被折叠?



