总之岁月漫长,然而值得等待。
——春上春树
一、策略模式介绍
策略模式是设计模式中行为模式的一种。它提供了在运行中改变一个类的行为的方法。
如下图,用户选择合适的策略去创建策略的使用者:
二、代码示例
1、需求场景
现在有一个需求:用户在支付的时候可以选择不同的支付方式,要求后续可以方便的增加新的支付方式。
2、实现
2.1 不使用策略模式的实现方式
使用一个支付方法,通过 if 判断传入的支付方式参数选择使用的支付方式。
这种方式代码臃肿,而且后续每增加一种支付方式都要修改这个类里面的代码,违反了设计模式中的开闭原则,对后续的扩展十分不友好。
/**
* 不使用策略模式
*
* @author ZhengNC
* @date 2020/8/14 8:53
*/
public class NoStrategyPattern {
/**
* 支付
*
* @param money 支付金额
* @param way 支付方式
*/
public void pay(BigDecimal money, String way){
if ("alipay".equals(way)){
System.out.println("通过支付宝支付:"+money.toString()+"元");
}else if ("weixinpay".equals(way)){
System.out.println("通过微信支付:"+money.toString()+"元");
}else if ("jdpay".equals(way)){
System.out.println("通过京东钱包支付:"+money.toString()+"元");
}else {
System.out.println("支付失败,不支持的支付方式:"+way);
}
}
}
2.2 使用策略模式的实现方式
使用策略模式需要创建以下几个类和接口:PayStrategy (策略接口)、AliPay (支付宝支付策略)、JDPay (京东支付策略)、WeiXinPay (微信支付策略)、PayContext (策略执行工具)。
PayStrategy:
import java.math.BigDecimal;
/**
* 支付策略接口
*
* @author ZhengNC
* @date 2020/8/14 9:07
*/
public interface PayStrategy {
/**
* 支付
*
* @param money 支付金额
*/
void doPay(BigDecimal money);
}
AliPay:
import java.math.BigDecimal;
/**
* 支付宝
*
* @author ZhengNC
* @date 2020/8/14 9:11
*/
public class AliPay implements PayStrategy {
@Override
public void doPay(BigDecimal money) {
System.out.println("通过支付宝支付:"+money.toString()+"元");
}
}
JDPay:
import java.math.BigDecimal;
/**
* @author ZhengNC
* @date 2020/8/14 9:13
*/
public class JDPay implements PayStrategy {
@Override
public void doPay(BigDecimal money) {
System.out.println("通过京东钱包支付:"+money.toString()+"元");
}
}
WeiXinPay:
import java.math.BigDecimal;
/**
* 微信支付
*
* @author ZhengNC
* @date 2020/8/14 9:12
*/
public class WeiXinPay implements PayStrategy {
@Override
public void doPay(BigDecimal money) {
System.out.println("通过微信支付:"+money.toString()+"元");
}
}
PayContext:
import java.math.BigDecimal;
/**
* 支付工具
*
* @author ZhengNC
* @date 2020/8/14 9:14
*/
public class PayContext {
/**
* 支付策略
*/
private PayStrategy payStrategy;
public PayContext(PayStrategy payStrategy) {
this.payStrategy = payStrategy;
}
/**
* 支付
*
* @param money 支付金额
*/
public void pay(BigDecimal money){
payStrategy.doPay(money);
}
}
2.3 测试
import java.math.BigDecimal;
/**
* 测试策略模式
*
* @author ZhengNC
* @date 2020/8/14 8:54
*/
public class TestStrategy {
public static void main(String[] args) {
//测试不使用策略模式
NoStrategyPattern payTool = new NoStrategyPattern();
payTool.pay(new BigDecimal("10.5"), "alipay");
payTool.pay(new BigDecimal("5.3"), "jdpay");
//测试使用策略模式
PayContext payContext = new PayContext(new AliPay());
payContext.pay(new BigDecimal("8.8"));
payContext = new PayContext(new WeiXinPay());
payContext.pay(new BigDecimal("6.6"));
}
}
运行结果:
通过支付宝支付:10.5元
通过京东钱包支付:5.3元
通过支付宝支付:8.8元
通过微信支付:6.6元