• 20 行为型模式-策略模式


    1 策略模式概述

    策略模式(strategy pattern)的原始定义是:定义一系列算法,将每一个算法封装起来,并使它们可以相互替换。策略模式让算法可以独立于使用它的客户端而变化。
    在这里插入图片描述
    在这里插入图片描述

    2 策略模式原理

    在这里插入图片描述

    3 策略模式实现

    策略模式的本质是通过Context类来作为中心控制单元,对不同的策略进行调度分配。

    //抽象策略类
    public interface Strategy {
    	void algorithm();
    }
    
    • 1
    • 2
    • 3
    • 4
    /**
     * 具体策略类
     **/
    public class ConcreteStrategyA implements Strategy {
    
        @Override
        public void algorithm() {
            System.out.println("执行策略A");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    public class ConcreteStrategyB implements Strategy {
    
        @Override
        public void algorithm() {
            System.out.println("执行策略B");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    /**
     * 上下文类: 策略模式的本质就是通过Context类作为控制单元,
     * 对不同的策略进行调度分配
     **/
    public class Context {
    
        //维持一个抽象策略的引用
        private Strategy strategy;
    
        public Context(Strategy strategy) {
            this.strategy = strategy;
        }
    
        //调用策略类中的算法
        public void algorithm(){
            strategy.algorithm();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    public class Client {
    
        public static void main(String[] args) {
    
            Strategy strategyB= new ConcreteStrategyB();
            Context context = new Context(strategyB);
    
            context.algorithm();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    1 ) 不使用设计模式
    /**
     * 回执信息
     **/
    public class Receipt {
    
        private String message; //回执内容
        private String type; //回执类型: MT1101、MT2101、MT4101、MT8104
    
        public Receipt() {
        }
    
        public Receipt(String message, String type) {
            this.message = message;
            this.type = type;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    }
    
    • 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
    • 32
    /**
     * 回执信息
     **/
    public class Receipt {
    
        private String message; //回执内容
        private String type; //回执类型: MT1101、MT2101、MT4101、MT8104
    
        public Receipt() {
        }
    
        public Receipt(String message, String type) {
            this.message = message;
            this.type = type;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    }
    
    • 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
    • 32
    public class Client {
    
        public static void main(String[] args) {
    
            List<Receipt> receiptList = ReceiptBuilder.getReceiptList();
    
            //回执类型: MT1101、MT2101、MT4101、MT8104
            for (Receipt receipt : receiptList) {
                if("MT1011".equals(receipt.getType())){
                    System.out.println("接收到MT1011的回执信息");
                    System.out.println("解析回执内容");
                    System.out.println("执行业务逻辑A......");
                }else if("MT2101".equals(receipt.getType())){
                    System.out.println("接收到MT2101的回执信息");
                    System.out.println("解析回执内容");
                    System.out.println("执行业务逻辑B......");
                }else if("MT4101".equals(receipt.getType())){
                    System.out.println("接收到MT4101的回执信息");
                    System.out.println("解析回执内容");
                    System.out.println("执行业务逻辑C......");
                }else if("MT8104".equals(receipt.getType())){
                    System.out.println("接收到MT8104的回执信息");
                    System.out.println("解析回执内容");
                    System.out.println("执行业务逻辑D......");
                }
                //.........
            }
        }
    }
    
    • 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
    2 ) 使用策略模式进行优化

    通过策略模式, 将所有的if-else分支的业务逻辑抽取为各种策略类,让客户端去依
    赖策略接口,保证具体策略类的改变不影响客户端.

    /**
     * 回执处理策略接口
     **/
    public interface ReceiptHandleStrategy {
        void handleReceipt(Receipt receipt);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    具体策略类

    /**
     * 具体策略类
     **/
    public class MT1101ReceiptHandleStrategy implements ReceiptHandleStrategy {
    
        @Override
        public void handleReceipt(Receipt receipt) {
            System.out.println("解析报文MT1101: " + receipt.getMessage());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    public class MT2101ReceiptHandleStrategy implements ReceiptHandleStrategy {
    
        @Override
        public void handleReceipt(Receipt receipt) {
            System.out.println("解析报文 MT2101: " + receipt.getMessage());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    策略上下文类(策略接口的持有者)

    /**
     * 上下文类, 持有策略接口,决定执行哪一个具体的策略类
     **/
    public class ReceiptStrategyContext {
    
        private ReceiptHandleStrategy receiptHandleStrategy;
    
        public void setReceiptHandleStrategy(ReceiptHandleStrategy receiptHandleStrategy) {
            this.receiptHandleStrategy = receiptHandleStrategy;
        }
    
        //调用策略类中方法
        public void handleReceipt(Receipt receipt){
            if(receipt != null){
                receiptHandleStrategy.handleReceipt(receipt);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    策略工厂

    /**
     * 策略工厂类
     **/
    public class ReceiptHandleStrategyFactory {
    
        public ReceiptHandleStrategyFactory() {
        }
    
        //使用Map集合存储策略信息,彻底的消除if...else
        private static Map<String,ReceiptHandleStrategy> strategyMap;
    
        //初始化具体策略,保存到map集合
        public static void init(){
            strategyMap = new HashMap<>();
    //        strategyMap.put("MT1101",new MT1101ReceiptHandleStrategy());
    //        strategyMap.put("MT2101",new MT2101ReceiptHandleStrategy());
            try {
                SAXReader reader = new SAXReader();
                String file = "I:\\MSB\\msb_work\\designpattern\\msb-strategy-pattern-14\\src\\main\\resources\\config.xml";
    
                Document document = reader.read(file);
                Node node = document.selectSingleNode("/confing/className");
                String className = node.getText();
                Class clazz = Class.forName(className);
                ReceiptHandleStrategy strategy = (ReceiptHandleStrategy) clazz.newInstance();
                strategyMap.put("MT1101",strategy);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //根据回执类型,获取对应的策略对象
        public static ReceiptHandleStrategy getStrategy(String receiptType){
            return strategyMap.get(receiptType);
        }
    }
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    public class Client {
    
        public static void main(String[] args) {
    
            //模拟回执
            List<Receipt> receiptList = ReceiptBuilder.getReceiptList();
    
            //策略上下文
            ReceiptStrategyContext context = new ReceiptStrategyContext();
    
            //策略模式最主要的工作: 将策略的 定义, 创建, 使用这三部分进行了解耦.
            for (Receipt receipt : receiptList) {
                //获取策略
                ReceiptHandleStrategyFactory.init();
                ReceiptHandleStrategy strategy = ReceiptHandleStrategyFactory.getStrategy(receipt.getType());
                //设置策略
                context.setReceiptHandleStrategy(strategy);
                //执行策略
                context.handleReceipt(receipt);
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    经过上面的改造,我们已经消除了if-else的结构,每当新来了一种回执,只需
    要添加新的回执处理策略,并修改ReceiptHandleStrategyFactory中的Map
    集合。如果要使得程序符合开闭原则,则需要调整ReceiptHandleStrategyFactory中处理策略的获取方式,通过反射的方式,获取指定包下的所IReceiptHandleStrategy实现类,然后放到字典Map中去.

    5 策略模式总结

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    王道考研操作系统——I/O管理
    照片相似性搜索引擎Embed-Photos;赋予大型语言模型(LLMs)视频和音频理解能力;OOTDiffusion的基础上可控制的服装驱动图像合成
    Java IO之网络的简介说明
    【Javascript】运算符(赋值,算术,自增,自减)
    Golang基础 基础数据类型之值类型
    Open Interpreter:OpenAI Code Interpreter的开源实现|本地化|可联网
    PMP项目管理实战 | 高效协作的团队从哪里来?
    Java数据结构、list集合、ArrayList集合、LinkedList集合、Vector集合
    ESP Insights:玩转设备标签
    【Python数据分析 - 6】:Numpy中的逻辑运算
  • 原文地址:https://blog.csdn.net/weixin_39563769/article/details/134038824