说明
这篇博客是在复杂场景使用策略和工厂模式代替分支语句升级版,增加了模版方法模式。将支付类的公共逻辑抽取到模板类中,使整个支付逻辑更加灵活,进一步优化了代码结构,提升了软件的可维护性和可读性。
流程图如下
先看一遍流程再对一下代码就能很深刻理解了。
代码具体改造
1、首先新增模版方法
public abstract class AbstractPaymentStrategy implements PaymentStrategy {
/**
* 模版方法 - 规定方法执行顺序,先check检查参数,再执行pay方法
*/
public final void commonPay(double amount) {
check(amount);
pay(amount);
}
/**
* 不希望子类去重写
*/
private void check(double amount) {
if (amount <= 0) {
throw new RuntimeException("无效的参数");
}
}
}
2、策略类由实现PaymentStrategy 接口改为继承模版方法
public class AlipayPaymentStrategy extends AbstractPaymentStrategy {
@Override
public boolean isSupport(String payMethod) {
return "AlipayPay".equals(payMethod);
}
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付:" + amount + "元。");
}
}
public class PayPalPaymentStrategy extends AbstractPaymentStrategy {
@Override
public boolean isSupport(String payMethod) {
return "PayPalPay".equals(payMethod);
}
@Override
public void pay(double amount) {
System.out.println("使用 PayPal 支付:" + amount + "元。");
}
}
public class UnionPayPaymentStrategy extends AbstractPaymentStrategy {
@Override
public boolean isSupport(String payMethod) {
return "UnionPay".equals(payMethod);
}
@Override
public void pay(double amount) {
System.out.println("使用银联支付:" + amount + "元。");
}
}
public class WeChatPaymentStrategy extends AbstractPaymentStrategy {
@Override
public boolean isSupport(String payMethod) {
return "WeChatPay".equals(payMethod);
}
@Override
public void pay(double amount) {
System.out.println("使用微信支付:" + amount + "元。");
}
}
3、策略工厂返回的策略接口改为返回模版类
/**
* 从注册的策略列表中获取策略
*/
public AbstractPaymentStrategy getStrategy(String payMethod) {
for (AbstractPaymentStrategy paymentStrategy : paymentStrategyList) {
if (paymentStrategy.isSupport(payMethod)) {
return paymentStrategy;
}
}
new Exception("支付方式不支持");
return null;
}
4、使用时调用模版方法代理直接调用pay()
public void strategyPay(double amount, String payMethod) {
PaymentFactory paymentFactory = PaymentFactory.getInstance();
AbstractPaymentStrategy strategy = paymentFactory.getStrategy(payMethod);
strategy.commonPay(amount);
}
测试check是否生效。
@Test
public void testStrategyPay() {
paymentService.strategyPay(100, "AlipayPay");
paymentService.strategyPay(100.0, "PayPalPay");
paymentService.strategyPay(100.0, "UnionPay");
paymentService.strategyPay(0, "WeChatPay");
}
使用支付宝支付:100.0元。
使用 PayPal 支付:100.0元。
使用银联支付:100.0元。
java.lang.RuntimeException: 无效的参数
结果符合预期。代码改造成功。