(十四)策略模式
策略模式(Stragey Pattern)指通过封装使得各个算法或组件可以互相替换和组合,在不同的场景选择不同的策略灵活处理问题。
1,策略模式的设计原则
上下文(Context):用来操作策略的上下文环境,屏蔽高层模块对算法的直接访问;
抽象策略(IStragey):策略或算法的顶级接口;
具体策略(ConcreteStragey):具体策略。
2,简单例子
支付场景中,通常会有多做支付方式供选择,使用策略模式对多种支付策略进行管理。
public abstract class Payment {
/**
* 抽象方法,子类需要重写,获得实现类方法名称
*
* @return
*/
public abstract String getName();
public MsgResult pay(String uid, double amout) {
if (queryBalance(uid) < amout) {
return new MsgResult("余额不足!", 500, "支付失败!");
}
return new MsgResult("支付成功!", 200, "支付金额" + amout);
}
protected abstract double queryBalance(String uid);
}
public class AliPay extends Payment {
@Override
public String getName() {
return "支付宝";
}
@Override
protected double queryBalance(String uid){
return 1000;
}
}
public class JDPay extends Payment{
@Override
public String getName() {
return "京东白条";
}
@Override
protected double queryBalance(String uid) {
return 200;
}
}
public class WechatPay extends Payment {
@Override
public String getName() {
return "微信支付";
}
@Override
protected double queryBalance(String uid) {
return 600;
}
}
public class MsgResult {
private String msg;
private int code;
private Object data;
public MsgResult(String msg, int code, Object data) {
this.msg = msg;
this.code = code;
this.data = data;
}
//getter,setter
}
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 MsgResult pay() {
return pay(PayStrategy.DEFAULT_PAY);
}
public MsgResult pay(String payKey) {
Payment payment = PayStrategy.get(payKey);
System.out.println("欢迎使用" + payment.getName());
System.out.println("本次交易金额" + amount + ",开始扣款");
return payment.pay(uid, amount);
}
}
/**
* 支付策略管理
*/
public class PayStrategy {
public static final String ALI_PAY = "AliPay";
public static final String JD_PAY = "JdPay";
public static final String WECHAT_PAY = "WechatPay";
public static final String DEFAULT_PAY = "AliPay";
private static Map<String, Payment> strategy = new HashMap<>();
static {
strategy.put(ALI_PAY, new AliPay());
strategy.put(JD_PAY, new JDPay());
strategy.put(WECHAT_PAY, new WechatPay());
}
public static Payment get(String payKey) {
if (!strategy.containsKey(payKey)) {
return strategy.get(DEFAULT_PAY);
}
return strategy.get(payKey);
}
}
public class Client {
public static void main(String[] args) {
Order order = new Order("1", "202103110007", 666);
// 通过构造方法抽象策略管理context灵活选择具体策略
System.out.println(order.pay(PayStrategy.WECHAT_PAY));
}
}
3,策略模式的评价
策略模式符合开闭原则,提供了对算法组的管理方法,能够灵活的对算法进行组合。缺点是客户端需要知道所有的策略,系统维护负担增加。