前言
策略模式是指定义了算法家族并分别分装起来,让他们之间可以互相替换,使得算法的变化不会影响使用算法的用户
策略模式最常用的场景是一个系统需要动态地在集中算法中选择,例如支付场景,接下来我们就以支付场景为里来解释策略模式
案例
定义支付抽象类Payment
首先我们定义支付抽象类
Payment :
public abstract class Payment {
public abstract String getName();
protected abstract double queryhBalance(String uid);
public PayState pay(String uid,double amount) {
if(queryhBalance(uid)<amount){
return new PayState(500,"支付失败","余额不足");
}
return new PayState(200,"支付成功","支付金额:"+amount);
}
}
这个抽象类是所有支付方式的父类,抽象了获得支付名称和查询账户余额的方法,并且定义了支付方法,在支付方法中,根据账户余额是否小于支付金额,返回不同的PayState
定义交易信息类PayState
PayState :
public class PayState {
private int code;
private Object data;
private String msg;
public PayState(int code,String msg,Object data) {
this.code = code;
this.data = data;
this.msg = msg;
}
public String toString() {
return ("支付状态:【"+code+"】,"+msg+",交易详情:"+data);
}
}
定义各种支付方式
我们生活中最常用的支付方式包括支付宝、微信、银联支付、京东白条等等
public class AliPay extends Payment{
@Override
public String getName() {
return "支付宝";
}
@Override
protected double queryhBalance(String uid) {
return 900;
}
}
public class WechatPay extends Payment{
@Override
public String getName() {
return "微信支付";
}
@Override
protected double queryhBalance(String uid) {
return 256;
}
}
public class UnionPay extends Payment{
@Override
public String getName() {
return "银联支付";
}
@Override
protected double queryhBalance(String uid) {
return 120;
}
}
public class JDPay extends Payment{
@Override
public String getName() {
return "京东白条";
}
@Override
protected double queryhBalance(String uid) {
return 500;
}
}
这些方式都继承了抽象支付类Payment,然后实现了getName和queryhBalance的方法
定义策略类
接下来是最关键了,定义策略类,在这个类中,我们生成了各种支付方式,并存放在Map中,然后get方法根据传入的值从Map中选择相应的支付方式返回
public class PayStrategy {
public static final String ALI_PAY = "AliPay";
public static final String JD_PAY = "jdPay";
public static final String UNION_PAY = "UnionPay";
public static final String WECHAT_PAY = "WechatPay";
public static final String DEFAULT_PAY = ALI_PAY;
private static Map<String,Payment> payStrategy = new HashMap<String,Payment>();
static {
payStrategy.put(ALI_PAY,new AliPay());
payStrategy.put(WECHAT_PAY,new WechatPay());
payStrategy.put(UNION_PAY,new UnionPay());
payStrategy.put(JD_PAY,new AliPay());
}
public static Payment get(String payKey) {
if(!payStrategy.containsKey(payKey)) {
return payStrategy.get(DEFAULT_PAY);
}
return payStrategy.get(payKey);
}
}
定义订单类
订单类就是使用策略的地方
public class Order {
private String uid;
private String orderId;
private double amount;
public Order(String uid,String orderId,double amount) {
this.uid = uid;
this.orderId = orderId;
this.amount = amount;
}
public PayState pay() {
return pay(PayStrategy.DEFAULT_PAY);
}
public PayState pay(String payKey) {
Payment payment = PayStrategy.get(payKey);
System.out.println("欢迎使用"+payment.getName());
System.out.println("本次交易金额为:"+amount+",开始扣款");
return payment.pay(uid,amount);
}
}
我们可以看到,订单类的的pay方法中根据传入payKey获得支付方式,然后调用支付方式对应的pay方法传入账户号和交易金额获得交易信息。
测试
public class Test {
public static void main(String[] args) {
Order order = new Order("1","202201090001000009",324.45);
System.out.println(order.pay(PayStrategy.ALI_PAY));
}
}