说明
这篇博客是在复杂场景使用策略和工厂模式代替分支语句升级版,增加了模版方法模式。将支付类的公共逻辑抽取到模板类中,使整个支付逻辑更加灵活,进一步优化了代码结构,提升了软件的可维护性和可读性。
流程图如下
先看一遍流程再对一下代码就能很深刻理解了。
代码具体改造
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 {@Overridepublic boolean isSupport(String payMethod) {return "AlipayPay".equals(payMethod);}@Overridepublic void pay(double amount) {System.out.println("使用支付宝支付:" + amount + "元。");}
}public class PayPalPaymentStrategy extends AbstractPaymentStrategy {@Overridepublic boolean isSupport(String payMethod) {return "PayPalPay".equals(payMethod);}@Overridepublic void pay(double amount) {System.out.println("使用 PayPal 支付:" + amount + "元。");}
}public class UnionPayPaymentStrategy extends AbstractPaymentStrategy {@Overridepublic boolean isSupport(String payMethod) {return "UnionPay".equals(payMethod);}@Overridepublic void pay(double amount) {System.out.println("使用银联支付:" + amount + "元。");}
}public class WeChatPaymentStrategy extends AbstractPaymentStrategy {@Overridepublic boolean isSupport(String payMethod) {return "WeChatPay".equals(payMethod);}@Overridepublic 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是否生效。
@Testpublic 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: 无效的参数
结果符合预期。代码改造成功。