JAVA设计模式中的策略模式你了解吗

 更新时间:2022年03月27日 16:12:23   作者:Asparrow  
这篇文章主要为大家详细介绍了JAVA设计模式中的策略模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

策略模式

世界上本没有模式;

一些程序老鸟在长时间的编程工作总结出高效的代码写法被后世推崇;

并整理出固定的写法规范,这个写法规范目前收录有23种

这些规范被称之为 --> 设计模式

策略模式是什么

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

策略模式的使用场景

Q: 我们知道策略模式最重要的就是封装变化点,那边对于变化点我们一般用什么处理呢?

A: 是的 我们一般用if - else 处理需要对变化点做出不同的反应,策略模式就可以替换代码中的if - else操作

其实策略模式主要就是替换代码中的if - else操作,当然也可以是switch

Q: 那我就有个疑问了,我就喜欢写if - else switch,我为什么要用策略模式呢,难道就是为了看起来牛逼吗?

A: 首先并不是所有的if - else switch 都适合使用策略模式改造,策略模式可谓是把双刃剑,使用时也会带来一些问题,比如说实现类膨胀;

Q: 既然是把双刃剑,那么如何判断是否应该使用策略模式呢?

A: 策略模式对标的是代码中的if - else操作,主要针对if - else 的嵌套层级和每个if - else下的代码处理行数;

(你的if - else 判断多余两次) && (每个if - else 下的处理代码超过5行) -> 建议使用策略模式优化代码

策略模式实践

我们使用一个简单的计算器需求来模拟策略模式的使用场景

/**
 * 计算器
 *
 * @author cans
 * @date 2022/3/26
 **/
public class Calculator {

    /**
     * 计算数字
     *
     * @param num1     参数1
     * @param num2     参数2
     * @param operator 操作算法
     * @return
     */
    public Integer calculate(Integer num1, Integer num2, String operator) {

        if(operator.equals("+")){
            return num1 + num2;
        }else if(operator.equals("-")){
            return num1 - num2;
        }
        throw new RuntimeException("无效的操作算法");
    }
}

以上代码使用if-else代码实现了一个简单的计算器代码,实现也完全没大问题,但是也存在弊端

1.扩展性不好,比如扩展乘法需要在代码中追加if-else

2.一两个if-else还好如果操作算法多了以后影响代码的可读性

下面使用策略模式对这个代码进行优化

/**
 * 使用策略模式进行优化
 *
 * @author cans
 * @date 2022/3/26
 **/
public class Calculator2 {

    private  Map<String,CalculatorOperator> calculatorOperatorMap = new HashMap<>();

    public Calculator2(){
        CalculatorOperatorAddImpl calculatorOperatorAdd = new CalculatorOperatorAddImpl();
        CalculatorOperatorSubImpl calculatorOperatorSub = new CalculatorOperatorSubImpl();
        calculatorOperatorMap.put(calculatorOperatorAdd.getOperator(),calculatorOperatorAdd);
        calculatorOperatorMap.put(calculatorOperatorSub.getOperator(),calculatorOperatorSub);
    }

    /**
     * 计算数字
     *
     * @param num1     参数1
     * @param num2     参数2
     * @param operator 操作算法
     * @return
     */
    public Integer calculate(Integer num1, Integer num2, String operator) {
        CalculatorOperator calculatorOperator = calculatorOperatorMap.get(operator);
        if(calculatorOperator == null){
            throw new RuntimeException("无效的操作算法:" + operator);
        }
        return calculatorOperator.calculate(num1, num2);
    }

    /**
     * 支持的算法枚举
     */
    public enum Operator{
        ADD("+"),SUB("-");

        private String operator;

        Operator(String operator){
            this.operator = operator;
        }

        public String getOperator() {
            return operator;
        }

        public void setOperator(String operator) {
            this.operator = operator;
        }
    }

    /**
     * 计算顶层接口
     */
    public interface CalculatorOperator{
        /**
         * 算法操作
         * @return
         */
        public String getOperator();

        /**
         * 计算方法
         *
         * @param num1 参数1
         * @param num2 参数2
         * @return
         */
        public Integer calculate(Integer num1, Integer num2);
    }

    /**
     * 加法实现
     */
    public class CalculatorOperatorAddImpl implements CalculatorOperator{

        @Override
        public String getOperator() {
            return Operator.ADD.getOperator();
        }

        /**
         * 加法操作
         * @param num1 参数1
         * @param num2 参数2
         * @return
         */
        public Integer calculate(Integer num1, Integer num2) {
         return num1 + num2;
        }
    }

    /**
     * 减法实现
     */
    public class CalculatorOperatorSubImpl implements CalculatorOperator{

        @Override
        public String getOperator() {
            return Operator.SUB.getOperator();
        }

        /**
         * 加法操作
         * @param num1 参数1
         * @param num2 参数2
         * @return
         */
        public Integer calculate(Integer num1, Integer num2) {
            return num1 - num2;
        }
    }

    @Test
    public void testCalculate(){
        System.out.println("1+1 = : " + calculate(1,1,"+"));
        System.out.println("1-1 = : " + calculate(1,1,"-"));
        System.out.println("1*1 = : " + calculate(1,1,"*"));
    }
}

策略模式以后类比较多,画个简单的图方便理解

在这里插入图片描述

其实这里结合工厂模式更好用,使用Map calculatorOperatorMap其实也一个意思;

可以看到使用策略模式以后类膨胀非常厉害,从之前1个类膨胀到4个类,但是扩展性得到了大大的提升,后续的算法扩展只需要在枚举中新增枚举类,实现响应的算法实现即可;

综上示例策略模式优势如下几点:

1.扩展性提升;

2.主体业务逻辑更清晰;

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!   

相关文章

  • 使用Java实现对两个秒级时间戳相加

    使用Java实现对两个秒级时间戳相加

    在现代应用程序开发中,时间戳的处理是一个常见需求,特别是当我们需要对时间戳进行运算时,比如时间戳的相加操作,本文我们将探讨如何使用Java对两个秒级时间戳进行相加,并展示详细的代码示例和运行结果,需要的朋友可以参考下
    2024-08-08
  • Java 十大排序算法之希尔排序刨析

    Java 十大排序算法之希尔排序刨析

    希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。本文会以图解的方式详细介绍希尔排序的基本思想及其代码实现
    2021-11-11
  • 基于红黑树插入操作原理及java实现方法(分享)

    基于红黑树插入操作原理及java实现方法(分享)

    下面小编就为大家分享一篇基于红黑树插入操作原理及java实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • 如何使用Spring AOP预处理Controller的参数

    如何使用Spring AOP预处理Controller的参数

    这篇文章主要介绍了如何使用Spring AOP预处理Controller的参数操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 一文读懂Spring Cloud-Hystrix

    一文读懂Spring Cloud-Hystrix

    这篇文章主要介绍了通过一文读懂Spring Cloud-Hystrix的相关知识,本文分步骤通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • java实现随机生成UUID

    java实现随机生成UUID

    这篇文章主要介绍了java实现随机生成UUID的函数代码,有需要的小伙伴可以参考下。
    2015-07-07
  • Java实现简单连连看游戏

    Java实现简单连连看游戏

    这篇文章主要为大家详细介绍了Java实现简单连连看游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java全面细致讲解类与对象

    Java全面细致讲解类与对象

    类和对象是两种以计算机为载体的计算机语言的合称。对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型;变量就是可以变化的量,存储在内存中—个可以拥有在某个范围内的可变存储区域
    2022-05-05
  • 在Java中避免NullPointerException的解决方案

    在Java中避免NullPointerException的解决方案

    这篇文章主要介绍了在Java中避免NullPointerException的解决方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 详解在Spring Boot框架下使用WebSocket实现消息推送

    详解在Spring Boot框架下使用WebSocket实现消息推送

    这篇文章主要介绍了详解在Spring Boot框架下使用WebSocket实现消息推送,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2016-12-12

最新评论