• 行为型设计模式之策略模式


    策略模式

    策略模式(Strategy Pattern)也叫政策模式(Policy Pattern),属于行为型模式。

    它是将定义的一系列算法、分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。

    策略模式能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。

    应用场景

    1、针对同一类型问题,有多种处理方式,每一种都能独立解决问题。
    
    2、算法需要自由切换的场景。
    
    3、需要屏蔽算法规则的场景。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    优缺点

    优点:

    1.可以在运行时切换对象内的算法。
    
    2.避免使用多重条件转移语句,如if.else.语句、switch语句
    
    3.使用策略模式可以提高算法的保密性和安全性。
    
    4.可以将算法的实现和使用算法的代码隔离开来。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    缺点:

    1.客户端必须知道所有的策略,所有策略类都需要对外暴露,并且自行决定使用哪一个策略类。
    
    2.代码中会产生非常多策略类,增加维护难度。
    
    • 1
    • 2
    • 3

    主要角色

    1.抽象策略角色(Strategy)

    规定策略或算法的行为。

    2.具体策略角色(ConcreteStrategy)

    具体的策略或算法实现。

    3.上下文角色(Context)

    用来操作策略的上下文环境,屏蔽高层模块(客户瑞)对策略,算法的直接访问,封装可能存在的变化。

    在这里插入图片描述

    策略模式的基本使用

    创建抽象策略角色

    public interface IStrategy {
        /**
         * 算法、策略
         */
        void algorithm();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    创建具体策略角色

    public class ConcreteStrategyA implements IStrategy {
        public void algorithm() {
            System.out.println("Strategy A 打9折");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public class ConcreteStrategyB implements IStrategy {
        public void algorithm() {
            System.out.println("Strategy B 打8折");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    创建上下文角色

    public class Context {
        private IStrategy mStrategy;
    
        public Context(IStrategy strategy) {
            this.mStrategy = strategy;
        }
    
        public void algorithm() {
            this.mStrategy.algorithm();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    客户端执行

        public static void main(String[] args) {
            // 创建具体策略
            IStrategy strategyA = new ConcreteStrategyA();
            IStrategy strategyB = new ConcreteStrategyB();
            // 创建上下文环境
            Context contextA = new Context(strategyA);
            Context contextB = new Context(strategyB);
            //客户端直接让上下文环境执行算法
            contextA.algorithm();
            contextB.algorithm();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    Strategy A9Strategy B8
    • 1
    • 2

    策略模式实现支付方式的选择

    创建抽象策略角色

    创建支付抽象类,定义支付逻辑

    public abstract class Payment {
    
        /**
         * 支付类型
         */
        public abstract String getName();
    
        /**
         * 支付
         * @param uid 用户id
         * @param amount 金额
         * @return 支付结果
         */
        public String pay(String uid, double amount){
            if(queryBalance(uid) < amount){
                return "支付失败,"+"商品金额:"+amount+" ,用户余额:"+queryBalance(uid);
            }
            return "支付成功,"+"商品金额:"+amount+" ,用户余额:"+(queryBalance(uid)-amount);
        }
    
        /**
         * 余额查询
         * @param uid 用户id
         * @return 余额
         */
        protected abstract double queryBalance(String uid);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    创建具体策略角色

    创建具体支付方式,如AliPay 、WechatPay 、UnionPay等三种方式。

    public class AliPay extends Payment {
        public String getName() {
            return "支付宝";
        }
    
        protected double queryBalance(String uid) {
            return 500;
        }
    }
    
    
    public class WechatPay extends Payment {
        public String getName() {
            return "微信支付";
        }
    
        protected double queryBalance(String uid) {
            return 600;
        }
    }
    
    
    public class UnionPay extends Payment {
        public String getName() {
            return "银联支付";
        }
    
        protected double queryBalance(String uid) {
            return 800;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    创建上下文角色

    创建上下文角色,

    public class PayStrategy {
        public static final String ALI_PAY = "AliPay";
        public static final String WECHAT_PAY = "WechatPay";
        public static final String UNION_PAY = "UnionPay";
        public static final String DEFAULT_PAY = ALI_PAY;
    
        private static Map<String, Payment> strategy = new HashMap<String, Payment>();
    
        static {
            strategy.put(ALI_PAY, new AliPay());
            strategy.put(WECHAT_PAY, new WechatPay());
            strategy.put(UNION_PAY, new UnionPay());
        }
    
        public static Payment get(String payKey) {
            if (!strategy.containsKey(payKey)) {
                return strategy.get(DEFAULT_PAY);
            }
            return strategy.get(payKey);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    客户端执行

    public class Order {
    
        private String uid;
        private String name;
        private double price;
    
        public Order(String uid, String name, double price) {
            this.uid = uid;
            this.name = name;
            this.price = price;
        }
    
        public String pay() {
            return pay(PayStrategy.DEFAULT_PAY);
        }
    
        public String pay(String payKey) {
            Payment payment = PayStrategy.get(payKey);
            System.out.println("购买:"+name+" ,使用" + payment.getName() + "支付, " + "支付金额为: " + price);
            return payment.pay(uid, price);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
        public static void main(String[] args) {
            Order order = new Order("001","皮皮虾",500.5);
            System.out.println(order.pay());
            System.out.println("----------------------------------------------------");
            System.out.println(order.pay(PayStrategy.WECHAT_PAY));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    购买:皮皮虾 ,使用支付宝支付, 支付金额为: 500.5
    支付失败,商品金额:500.5 ,用户余额:500.0
    ----------------------------------------------------
    购买:皮皮虾 ,使用微信支付支付, 支付金额为: 500.5
    支付成功,商品金额:500.5 ,用户余额:99.5
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    SAP如何批量标记生产订单的TECO状态
    LeetCode讲解篇之面试题 01.08. 零矩阵
    面向大数据存算分离场景的数据湖加速方案
    TCP协议之《套接口sk_backlog接收队列》
    UsernamePasswordAuthenticationFilter执行流程
    【深入浅出Nginx系列】Nginx入门?看这一篇就够了(实战篇)
    【Git】第一篇:Git安装(centos)
    Java之运算符(4)
    网关BL100做主站采集从机设备上云平台示例
    docker学习笔记
  • 原文地址:https://blog.csdn.net/qq_38628046/article/details/126196514