• 策略模式


    策略模式:

      策略模式(Strategy Pattern)是指定义了算法家族并分别封装起来,让他们之间可以互相替换,此模式使用得算法的变化不会影响使用算法的用户。

    应用场景:

      (1)系统中有很多类,而他们的区别仅仅在于行为不同。

      (2)一个系统需要动态地在几种算法中选择一种。

      例如:大家都用过支付宝支付、微信支付、银联支付、以及京东白条支付。一个常见的应用场景就是大家在支付时会提示选择支付方式,如果用户未选择,系统会使用默认的支付方式进行结算。

      使用策略模式模拟次业务场景。

      创建 Payment 抽象类,定义支付规范和支付逻辑:

    package com.xq.design.startegy.pay.payport;
    
    import com.xq.design.startegy.pay.PayState;
    
    public abstract class Payment {
    
        //支付类型
        public abstract String getName();
    
        //查询余额
        protected  abstract double queryBalance(String uid);
    
        //扣款支付
        public PayState pay(String uid, double amount){
            if(queryBalance(uid) < amount){
                return new PayState(500,"支付失败","余额不足");
            }
            return new PayState(200,"支付成功","支付金额:" + amount);
        }
    }

      分别创建具体的支付方式,支付宝支付类 AliPay:

    package com.xq.design.startegy.pay;
    
    import com.xq.design.startegy.pay.payport.Payment;
    
    public class AliPay extends Payment {
        @Override
        public String getName() {
            return "支付宝";
        }
    
        @Override
        protected double queryBalance(String uid) {
            return 900;
        }
    }

      银联支付类 UnionPay :

    package com.xq.design.startegy.pay;
    
    import com.xq.design.startegy.pay.payport.Payment;
    
    public class UnionPay extends Payment {
        @Override
        public String getName() {
            return "银联支付";
        }
    
        @Override
        protected double queryBalance(String uid) {
            return 120;
        }
    }

      京东白条支付类 JDPay:

    package com.xq.design.startegy.pay;
    
    import com.xq.design.startegy.pay.payport.Payment;
    
    public class JDPay extends Payment {
        @Override
        public String getName() {
            return "京东白条";
        }
    
        @Override
        protected double queryBalance(String uid) {
            return 500;
        }
    }

      创建支付状态的包装类 PayState:

    package com.xq.design.startegy.pay;
    
    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;
        }
    
        public String toString(){
            return ("支付状态:【" + code +"】," + msg + ",交易详情:" + data);
        }
    }

      创建支付策略管理类 PayStrategy:

    package com.xq.design.startegy.pay.payport;
    
    import com.xq.design.startegy.pay.AliPay;
    import com.xq.design.startegy.pay.JDPay;
    import com.xq.design.startegy.pay.UnionPay;
    import com.xq.design.startegy.pay.WechatPay;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class PayStrategy {
        public static final String ALI_PAUY = "AliPay";
        public static final String JD_PAY = "jdPay";
        public static final String UNION_PAY = "UnionPay";
        public static final String WECHAT_PAY = "WechatPay";
        public static final String DEFAULT_PAY = ALI_PAUY;
    
        private static Map<String,Payment> payStrategy = new HashMap<String,Payment>();
        static{
            payStrategy.put(ALI_PAUY, new AliPay());
            payStrategy.put(WECHAT_PAY, new WechatPay());
            payStrategy.put(UNION_PAY, new UnionPay());
            payStrategy.put(JD_PAY, new JDPay());
        }
        public static Payment get(String payKey){
            if(!payStrategy.containsKey(payKey)){
                return payStrategy.get(payKey);
            }
            return payStrategy.get(payKey);
        }
    }

      创建订单类 Order:

    package com.xq.design.startegy.pay;
    
    import com.xq.design.startegy.pay.payport.PayStrategy;
    import com.xq.design.startegy.pay.payport.Payment;
    
    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;
        }
        //完美的解决了 switch 过程,不需要再代码中写switch了,更不需要写 if ... else if
        public PayState pay(){
            return  pay(PayStrategy.DEFAULT_PAY);
        }
    
        public PayState pay(String paykKey) {
            Payment payment = PayStrategy.get(paykKey);
            System.out.println("欢迎使用" + payment.getName());
            System.out.println("本次交易金额为:" + amount + ",开始扣款...");
            return payment.pay(uid,amount);
        }
    }

      测试代码如下:

    package com.xq.design.startegy.pay;
    
    import com.xq.design.startegy.pay.payport.PayStrategy;
    
    public class PayStrategyTest {
        public static void main(String[] args) {
            Order order = new Order("1","202005130000001",326.5);
            /**
             * 开始支付,选择支付方式
             * 每个渠道支付的具体算法是不一样的,基本算法是固定的
             * 在支付的时候才决定这个值是用哪个
             */
            System.out.println(order.pay(PayStrategy.ALI_PAUY));
        }
    }

      结果如下:

     策略模式的优缺点

      策略模式有点如下:

      (1)策略模式符合开闭原则。  

      (2)策略模式可避免使用多重条件语句,如 if...else 语句、switch语句。

      (3)使用策略模式可以提高算法的保密性和安全性。

      策略模式的缺点如下:

      (1)客户端必须知道所有的策略,并且自行决定使用哪一个策略类。

      (2)代码中会产生非常多的策略类,增加了代码的维护难度。

    博客园:https://www.cnblogs.com/xianquan
    Copyright ©2020 l-coil
    【转载文章务必保留出处和署名,谢谢!】
  • 相关阅读:
    随笔:我为什么要写博客?
    用纯C语言写的一个植物大战僵尸的外挂
    方法:如何获取操作系统所有分区(逻辑驱动器)
    Srping syntactically incorrect.错误记录
    重建项目报错
    easyui datagrid 跨页选择
    CentOS 6编译安装ipvsadm和keepalived
    CentOS 6下ActiveMQ 5.5安装及使用MySQL
    extjs 4中TreePanel和GridPanel使用
    Linux安装性能问题
  • 原文地址:https://www.cnblogs.com/xianquan/p/12881288.html
  • Copyright © 2020-2023  润新知