亲宝软件园·资讯

展开

JAVA策略模式

Asparrow 人气:2

策略模式

世界上本没有模式;

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

并整理出固定的写法规范,这个写法规范目前收录有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.主体业务逻辑更清晰;

总结

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

加载全部内容

相关教程
猜你喜欢
用户评论