• 策略模式


    1. 定义

    定义一系列算法,把他们一个个封装起来,并且使他们可以互相替换。本模式使得算法
    可以独立于使用它的客户而变化。

    2. 策略模式的结构

    策略模式结构图

    • Strategy : 策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法
    • ConcreteStrategy:具体的策略实现,也就是具体的算法实现。
    • Context:上下文,负责和具体具体的策略类交互。

    3. 本质

    分离算法,选择实现

    4. 实例

    下面以订单支付支付为场景为例来演示策略模式:网上买东西订单支付一般会选择支付宝支付,微信支付,银联支付等等支付方式来实现。如果我们要实现这个功能其实很简单。下面给出不采用设计模式的实现:

    Payment

    /**
     * 支付 的策略接口
     * @author lijun
     * @since 2018-03-16 13:48
     */
    public interface Payment {
        /**
         * 支付接口
         * @param userId 用户ID
         * @param amount 支付金额
         * @return PayState 支付状态
         */
        PayState pay(String userId,double amount);
    }

    AliPay

    /**
     * 支付宝支付
     * @author lijun
     * @since 2018-03-16 13:57
     */
    public class AliPay implements Payment {
        /**
         * 支付接口
         *
         * @param userId 用户ID
         * @param amount 支付金额
         * @return PayState 支付状态
         */
        @Override
        public PayState pay(String userId, double amount) {
            System.out.println("欢迎使用支付宝");
            System.out.println("查询账户余额,开始扣款");
            return new PayState(200,"支付成功",amount);
        }
    }

    WechatPay

    /**
     * 微信支付
     * @author lijun
     * @since 2018-03-16 14:02
     */
    public class WechatPay implements Payment {
        /**
         * 支付接口
         *
         * @param userId 用户ID
         * @param amount 支付金额
         * @return PayState 支付状态
         */
        @Override
        public PayState pay(String userId, double amount) {
            System.out.println("欢迎使用微信支付");
            System.out.println("直接从微信红包扣款");
            return new PayState(200,"支付成功",amount);
        }
    }
    

    PayState

    /**
     * 支付状态
     * @author lijun
     * @since 2018-03-16 13:56
     */
    public class PayState {
        private int code;
        private Object data;
        private String msg;
    
        public PayState(int code, String msg, Object data) {
            this.code = code;
            this.data = data;
            this.msg = msg;
        }
    
        @Override
        public String toString() {
            return ("支付状态:[" + code + "]," + msg + ",交易详情:" + data);
        }
    }

    OrderNoStrategy

    /**
     * OrderNoStrategy
     *
     * @author lijun
     * @since 2018-03-16 14:24
     */
    public class OrderNoStrategy {
    
        /**
         * 阿里支付
         */
        private static final String ALI_PAY = "1";
    
        private static final String WX_PAY = "1";
    
        /**
         * 支付
         *
         * @param userId    用户ID
         * @param amount    支付金额
         * @param orderType 支付类型
         * @return
         */
        PayState pay(String userId, double amount, String orderType) {
            Payment payment = null;
            if (ALI_PAY.equals(orderType)) {
                payment = new AliPay();
            } else if (WX_PAY.equals(orderType)) {
                payment = new WechatPay();
            } else {
                payment = new AliPay();
            }
            return payment.pay(userId, amount);
        }
    }
    

    调用:

      @Test
        public void payNoStrategy() throws Exception {
            OrderNoStrategy order = new OrderNoStrategy();
            PayState payState = order.pay("lijun", 200,"1");
            System.out.println(payState);
        }

    输出:

    欢迎使用支付宝
    查询账户余额,开始扣款
    支付状态:[200],支付成功,交易详情:200.0

    功能是实现了,但是有什么缺点呢!上面只是实现了支付宝支付和微信支付,如果再添加银联卡支付OrderNoStrategy.pay() 得再加一个else if 如果支付渠道变的很多就会出现非常的多的if else if 。怎么消除这些if else 使用策略模式。 Payment 相当于(策略接口) AliPay(策略的实现) WechatPay(策略的实现) Order(上下文) 。

    Order

    /**
     * 订单
     *
     * @author lijun
     * @since 2018-03-16 14:03
     */
    public class Order {
    
        /**
         * payment 支付接口
         */
        private Payment payment;
    
        public Order(Payment payment) {
            this.payment = payment;
        }
    
        /**
         * 上下文支付 和具体的策略类交互
         *
         * @param userId
         * @param amount
         * @return
         */
        PayState pay(String userId, double amount) {
            return payment.pay(userId, amount);
        }
    }

    测试:

       @Test
        public void pay() throws Exception {
            Order order = new Order(new AliPay());
            PayState payState = order.pay("lijun", 200);
            System.out.println(payState);
        }

    输出:

    欢迎使用支付宝
    查询账户余额,开始扣款
    支付状态:[200],支付成功,交易详情:200.0

    这样利用策略模式实现了支付,如果要再添加一种支付,变的非常简单只需要实现Payment 其他代码都不需要修改!客户端测试只需要传入新添加的支付的实现类即可。这样就消除了多个 if else。

    源码地址

  • 相关阅读:
    pointer-like classes, 关于智能指针
    non-explicite-one-argumen-constructor
    车道标线分割与分类
    matlab变量更新
    matlab求余
    MATLAB中图像的读取与显示
    提取文件一部分内容
    NetCore3.1 使用 mongoDb 存储日志,提升查询效率
    C#代码实现阿里云消息服务MNS消息监听
    盘点这些年我出的书,以及由此得到的收获
  • 原文地址:https://www.cnblogs.com/mokingone/p/9109010.html
Copyright © 2020-2023  润新知