1、基本概念
策略模式( Strategy Pattern )又叫也叫政策模式( Policy Pattern) , 它是将定义的算法家族、分
别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。属于行为型模
式。
策略模式使用的就是面向对象的继承和多态机制,从而实现同-行为在不同场景下具备不同实现。
比如:登录系统时的权限,有管理员,普通用户,vip用户,超级管理员等,不同的用户登录选择不同的策略
来获取系统的权限。订单支付时,有微信支付,支付宝支付,银联支付等,选择不同的支付方式策略,来实现支付的逻辑。
2、类图和角色
类图:
主要角色:
抽象策略:IStrategy,规定策略的行为
具体策略:ConcreteStrategyA,ConcreteStrategyB,ConcreteStrategyC,策略的具体实现
上下文:Context,用来操作策略
3、案例
案例:订单支付选择支付方式,有微信支付,支付宝支付,银联支付
类图:
该结构中,加了抽象类AbstractPayStrategy,来实现一部分的支付逻辑
策略接口:IPayStrategy
public interface IPayStrategy { String pay(Integer price); }
抽象策略类:AbstractPayStrategy
定义一个支付的流程,具体的由子类去实现,这也是个模板方法模式。
public abstract class AbstractPayStrategy implements IPayStrategy { private IPayStrategy iPayStrategy; @Override public String pay(Integer price) { if (checkMoneyIsEnough() < price) { return "当前支付方式余额不足"+",商品价格:"+price; }; return this.executePay(price); } protected abstract String executePay(Integer price); protected abstract Integer checkMoneyIsEnough(); }
具体实现类中,有具体支付的逻辑处理,这里简单处理,直接返回字符串
具体实现类:Alipay
public class Alipay extends AbstractPayStrategy{ @Override protected String executePay(Integer price) { return "支付宝支付成功 ,支付金额"+price; } @Override protected Integer checkMoneyIsEnough() { return 10000; } }
具体实现类:Unionpay
public class Unionpay extends AbstractPayStrategy{ @Override protected String executePay(Integer price) { return "银联支付成功 ,支付金额"+price; } @Override protected Integer checkMoneyIsEnough() { return 400; } }
具体实现类:WechatPay
public class WechatPay extends AbstractPayStrategy{ @Override protected String executePay(Integer price) { return "微信支付成功,支付金额"+price; } @Override protected Integer checkMoneyIsEnough() { return 50; } }
上下文:PayContext,当客户端传入支付类型时,为避免if else 这样的判断,这里将策略进行初始化操作,做一个map缓存
在实际开发中,策略的获取,我们可以放在数据库中获取,也可以放在配置文件中,如spring cloud alibaba nacos中。
public class PayContext { public static final Map<String,IPayStrategy> stategyMap = new HashMap<>(); private static final Alipay DEFAULT_PAY = new Alipay(); static { stategyMap.put("WEIXIN",new WechatPay()); stategyMap.put("UNINO",new Unionpay()); stategyMap.put("ALIPAY",new Alipay()); } public static IPayStrategy getPayStrategy(String payType){ if(!stategyMap.containsKey(payType)){ return DEFAULT_PAY; } IPayStrategy iPayStrategy = stategyMap.get(payType); return iPayStrategy; } }
测试:
public class Test { public static void main(String[] args) { int price = 500; String payType = "ALIPAY"; IPayStrategy payStrategy = PayContext.getPayStrategy(payType); String rs = payStrategy.pay(price); System.out.println(rs); String payType2 = "WEIXIN"; IPayStrategy payStrategy2 = PayContext.getPayStrategy(payType2); String rs2 = payStrategy2.pay(price); System.out.println(rs2); } }
输出:
支付宝支付成功 ,支付金额500
当前支付方式余额不足,商品价格:500
4、优缺点
优点:
1、策略模式符合开闭原则。
2、避免使用多重条件转移语句,如iif else ...语句. switch 语句
3、使用策略模式可以提高算法的保密性和安全性。