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

  • 相关阅读:
    Google Chrome开发者工具
    自动跳转页面
    Java读取properties配置文件
    Linux(CentOS):安装JDK + MySQL + FTP
    MySQL数据库完全卸载
    Java冒泡排序
    Java选择排序
    Java多线程总结
    数据库索引(Oracle和MySql)
    Oracle数据库
  • 原文地址:https://www.cnblogs.com/tdyang/p/13278128.html
Copyright © 2020-2023  润新知