概述
策略模式(Strategy Pattern)又叫也叫政策模式(Policy Pattern),它是将定义的算法家族分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。
可以避免多重分支的if. ..else.. .和switch语句
属于行为型模式。
场景
阶梯个税
支付方式选择
1、假如系统中有很多类.而他们的区别仅仅在于他们的行为不同
2、一个系统需要动态地在几种算法中选择一种。
3、需要屏蔽算法规则。
优点
1、策略模式符合开闭原则;
2、避免使用多重条件转移语句,如if...else...语句、switch语句
3、使用策略模式可以提高算法的保密性和安全性。
缺点
1、客户端必须知道所有的等略.并自定决定使用那一个策略;
2、代码中会产生非常多策略类,增加维护难度;
举个栗子#计算
public interface IStrategy {
void algorithm();
}
public class ConcreteStrategyA implements IStrategy {
@Override
public void algorithm() {
System.out.println("Strategy A");
}
}
public class ConcreteStrategyB implements IStrategy {
public void algorithm() {
System.out.println("Strategy B");
}
}
// 算法上下文,
public class Context {
private IStrategy mStrategy;
public Context(IStrategy strategy) {
this.mStrategy = strategy;
}
public void algorithm() {
this.mStrategy.algorithm();
}
}
public class Test {
public static void main(String[] args) {
//选择一个具体策略
IStrategy strategy = new ConcreteStrategyA();
//来一个上下文环境
Context context = new Context(strategy);
//客户端直接让上下文环境执行算法
context.algorithm();
}
}
图1-1
举个栗子#支付
public abstract class Payment {
public abstract String getName();
//通用逻辑放到抽象类里面实现
public MsgResult pay(String uid, double amount){
//余额是否足够
if(queryBalance(uid) < amount){
return new MsgResult(500,"支付失败","余额不足");
}
return new MsgResult(200,"支付成功","支付金额" + amount);
}
protected abstract double queryBalance(String uid);
}
public class AliPay extends Payment {
@Override
public String getName() {
return "支付宝";
}
@Override
protected double queryBalance(String uid) {
return 900;
}
}
public class JDPay extends Payment {
@Override
public String getName() {
return "京东白条";
}
@Override
protected double queryBalance(String uid) {
return 500;
}
}
public class UnionPay extends Payment {
@Override
public String getName() {
return "银联支付";
}
@Override
protected double queryBalance(String uid) {
return 120;
}
}
public class WechatPay extends Payment {
@Override
public String getName() {
return "微信支付";
}
@Override
protected double queryBalance(String uid) {
return 263;
}
}
// 策略锦囊
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 UNION_PAY = "UnionPay";
public static final String DEFAULT_PAY = ALI_PAY;
private static Map<String,Payment> strategy = new HashMap<String,Payment>();
static {
strategy.put(ALI_PAY,new AliPay());
strategy.put(JD_PAY,new JDPay());
strategy.put(WECHAT_PAY,new WechatPay());
strategy.put(UNION_PAY,new UnionPay());
}
public static Payment get(String payKey){
if(!strategy.containsKey(payKey)){
return strategy.get(DEFAULT_PAY);
}
return strategy.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 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 MsgResult {
private int code;
private Object data;
private String msg;
public MsgResult(int code, String msg, Object data) {
this.code = code;
this.data = data;
this.msg = msg;
}
@Override
public String toString() {
return "MsgResult{" +
"code=" + code +
", data=" + data +
", msg='" + msg + '\'' +
'}';
}
}
public class Test {
public static void main(String[] args) {
Order order = new Order("1","2020031401000323",324.5);
System.out.println(order.pay(PayStrategy.DEFAULT_PAY));
}
}
图1-2:
源码实现#Comparator
int compare(T o1, T o2);
Spring#Rsource
public interface Resource extends InputStreamSource