首页 > 技术文章 > 设计模式学习之策略模式

wgyang 2020-04-04 20:01 原文

策略模式是一种定义一系列算法的方法。从概念上看,策略模式的重点在于封装。比如在计算器这个例子中,能够计算是计算器的一个功能,但是不同的计算方法会产生不同的计算结果,运用策略模式,将不同的计算方法单独封装起来,客户端再根据实际的输入条件选择相应的计算方法。

策略模式的优点:

  1. 对算法进行了封装,减少了算法类与调用算法的类之间的耦合性
  2. 策略模式能够简化算法的单元测试,每个算法都有单独的类,可以通过自己的接口进行单独的测试

计算器的例子:

/**
 * @author wgyang
 * Create time: 2020-04-04 15:34
 * Description:
 */
public interface Operator {

    /**
     * 计算
     *
     * @param number1 数字1
     * @param number2 数字2
     * @return 返回计算的结果
     */
    String calculate(int number1, int number2);
}
/**
 * @author wgyang
 * Create time: 2020-04-04 15:44
 * Description: 加法操作
 */
public class OperatorAdd implements Operator {
    public String calculate(int number1, int number2) {
        return String.valueOf(number1 + number2);
    }
}
/**
 * @author wgyang
 * Create time: 2020-04-04 15:50
 * Description: 出发操作
 */
public class OperatorDivision implements Operator {
    public String calculate(int number1, int number2) {
        if (number2 == 0) {
            return "除数不能为0";
        } else {
            return String.valueOf(number1 / number2);
        }
    }
}
/**
 * @author wgyang
 * Create time: 2020-04-04 15:49
 * Description: 乘法操作
 */
public class OperatorMultiplication implements Operator {
    public String calculate(int number1, int number2) {
        return String.valueOf(number1 * number2);
    }
}
/**
 * @author wgyang
 * Create time: 2020-04-04 15:48
 * Description: 减法操作
 */
public class OperatorSubtraction implements Operator {
    public String calculate(int number1, int number2) {
        return String.valueOf(number1 - number2);
    }
}
/**
 * @author wgyang
 * Create time: 2020-04-04 15:56
 * Description: 选择操作的算法,计算除结果
 */
public class OperateStrategy {
    private Operator operator;

    public OperateStrategy(String operate) {
        switch (operate) {
            case "+":
                this.operator = new OperatorAdd();
                break;
            case "-":
                this.operator = new OperatorSubtraction();
                break;
            case "*":
                this.operator = new OperatorMultiplication();
                break;
            case "/":
                this.operator = new OperatorDivision();
                break;
            default:
                throw new UnsupportedOperationException(String.format("不支持的操作类型:%s", operate));
        }
    }

    public String getCalculateResult(int number1, int number2) {
        return this.operator.calculate(number1, number2);
    }
}
/**
 * @author wgyang
 * Create time: 2020-04-04 15:32
 * Description: 实现一个简单的计算器,输入两个整数,对其进行加、减、乘、除运算,运用策略模式与简单工厂模式
 */
public class Calculator {
    public static void main(String[] args) {
        int number1 = 2;
        int number2 = 5;
        System.out.println(new OperateStrategy("+").getCalculateResult(number1, number2));

        System.out.println(new OperateStrategy("-").getCalculateResult(number1, number2));

        System.out.println(new OperateStrategy("*").getCalculateResult(number1, number2));

        System.out.println(new OperateStrategy("/").getCalculateResult(number1, number2));

        //求余计算不支持,抛出异常
        System.out.println(new OperateStrategy("%").getCalculateResult(number1, number2));
    }
}

在上面的例子中,除了策略模式,还用到了简单工厂模式。如果只是策略模式,算法的判断会导致需要在客户端中出现许多if语句。例子中将工厂模式结合,在OperateStrategy类中运用了一个工厂方法,使客户端中的if语句消失了。同时,与单独的工厂模式相比,客户端依赖的类变少了,在简单工厂模式的例子中,客户端代码需要依赖Operator类和OperatorFactory类。

推荐阅读