java设计模式(十一)——策略模式

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、使用策略模式可以提高算法的保密性和安全性。

原文地址:https://www.cnblogs.com/tdyang/p/13278128.html