• 策略模式在不同情况下的使用方法


    概述

    策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。

    把行为和环境分割开来。环境类Context负责查询要做什么,各种算法则在具体策略类(ConcreteStrategy)中提供。

    在这里插入图片描述

    提出问题

    假设有一个计算的功能,分别有加减乘三种方法,如果需要通过传入的一个type去判断具体执行哪一个方法

    如果使用传统的方法的话,我们就需要去使用多个if判断,现在只需要两三个,那么如果后面这种有几十种呢?

    所以,在这里就需要去使用策略模式去解决,下面便对策略模式进行解决这个问题

    演示1(Java代码)

    演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化

    接口(Strategy )

    策略接口的定义,通常包含:处理策略业务逻辑的方法。

    public interface Strategy {
       public int doOperation(int num1, int num2);
    }
    
    • 1
    • 2
    • 3

    实现(implements)

    创建实现接口的实体类,这样我们可以灵活的替换不同的实现方法

    OperationAdd(加)

    public class OperationAdd implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 + num2;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    OperationSubtract(减)

    public class OperationSubtract implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 - num2;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    executeStrategy(乘)

    public class executeStrategy implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 * num2;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    上下文类(Context)

    策略模式包含一组同类的策略,在使用时我们通常通过类型来判断创建哪种策略来进行使用

    上下文类,就是集成算法的类

    该类的定义体现了多用组合,少用继承。针对接口,不针对实现两个设计原则。

    public class Context {
       private Strategy strategy;
     
       public Context(Strategy strategy){
          this.strategy = strategy;
       }
     
       public int executeStrategy(int num1, int num2){
          return strategy.doOperation(num1, num2);
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    使用

    public class StrategyPatternDemo {
       public static void main(String[] args) {
          Context context = new Context(new OperationAdd());    
          System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
     
          context = new Context(new OperationSubtract());      
          System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
     
          context = new Context(new OperationMultiply());    
          System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    输出结果:

    10 + 5 = 15
    10 - 5 = 5
    10 * 5 = 50
    
    • 1
    • 2
    • 3

    演示3(使用反射)

    在这里假设上面的三种实现类都是在com.app里面

    package com.app;
    
    
    public class T1 {
    
    	public static void main(String[] args) {
    
    		try {
    			//创建类
    			String type = "concreteStrategyA ";
    			Class<?> class1 = Class.forName("com.app" + type);;
    			//创建实例化:相当于 new 了一个对象
    			Object object = class1.newInstance() ;
    			//向下转型				
    			OperationAdd add = (OperationAdd) object ;
    			System.out.println("10 - 5 = " + add.doOperation(10, 5));
    			
    			
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		} catch (InstantiationException e) {
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			e.printStackTrace();
    		}
    
    	}
    }
    
    
    
    • 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

    演示3(Spring简单工厂实现)

    上面的代码有一点问题,那就是我们需要去new一个对象(反射的也是需要new已一个),如果在Spring项目中,通过new创建出来的对象中,无法使用@Resource或@Autowired 注解实例化service层注入。
    因为Spring的注入是在项目启动的时候执行的,所以后期new出来的实例对象中的注入注解就不会生效了

    接口(Strategy)

    public interface Strategy {
       public int doOperation(int num1, int num2);
    }
    
    • 1
    • 2
    • 3

    实现(implements)

    创建实现接口的实体类,这样我们可以灵活的替换不同的实现方法

    OperationAdd(加)

    @Component("add")
    public class OperationAdd implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 + num2;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    OperationSubtract(减)

    @Component("substract")
    public class OperationSubtract implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 - num2;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    executeStrategy(乘)

    @Component("multiply")
    public class executeStrategy implements Strategy{
       @Override
       public int doOperation(int num1, int num2) {
          return num1 * num2;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    上下文类/工厂类(Context)

    策略模式包含一组同类的策略,在使用时我们通常通过类型来判断创建哪种策略来进行使用

    上下文类,就是集成算法的类

    该类的定义体现了多用组合,少用继承。针对接口,不针对实现两个设计原则。

    @Component
    public class Context {
       
       	@Autowired
        private Map<String, Strategy> strategyMap;
     
       public Strategy build(String type){
          return strategyMap.get(type);
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用

    @Component
    public class StrategyPatternDemo {
        @Autowired
        private Context context;
    	
    	public void test(){
    		Strategy strategy = context.build("add");
    		int add = startegy.doOperation(10, 5);
    		System.out.println("10 + 5 = " + add);
    		
    		Strategy strategy = context.build("subtract");
    		int subtract = startegy.doOperation(10, 5);
    		System.out.println("10 - 5 = " + subtract);
    		
    		Strategy strategy = context.build("multiply");
    		int multiply = startegy.doOperation(10, 5);
    		System.out.println("10 * 5 = " + multiply);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    输出结果:

    10 + 5 = 15
    10 - 5 = 5
    10 * 5 = 50
    
    • 1
    • 2
    • 3
  • 相关阅读:
    2023国赛数学建模D题思路模型代码 高教社杯
    JWT 破解
    SpringCloud的五大组件简介
    DDOS直接攻击系统资源
    MySQL学习5:事务、存储引擎
    对信息系统生命周期各阶段进行风险评估的要点汇总
    ROS1云课→25机器人控制配置
    思维导图制作工具推荐
    ssm基于javaweb体育运动会竞赛成绩管理系统springboot
    详解linux内核链表list_head及其接口应用
  • 原文地址:https://blog.csdn.net/yyuggjggg/article/details/126669687