设计模式-策略模式

这次主要记录下策略模式的学习过程


一、什么是策略模式

  • 策略模式(Strategy Pattern):定义了算法家族,并分别封装起来,让他们之间可以互相替换
  • 优点:
    • 各个算法之间可以自由切换
    • 可以避免使用多重条件判断
    • 遵循开闭原则,扩展性良好
  • 缺点:
    • 策略类会越来越多,增加开发量
    • 所有策略类都需要对外暴露,需要手动判断使用哪个算法
  • 策略模式与工厂模式的区别:
    • 侧重点不同
      • 工厂模式关注的是:对象的创建
      • 策略模式关注的是:行为的封装
    • 作用不同
      • 工厂模式的作用是:创建对象
      • 策略模式的作用是:让一个对象在多种行为中选择一种行为

二、策略模式UML图

在这里插入图片描述


三、策略模式示例

运算方法抽象类
即策略类,定义了所有支持的算法的公共接口

/**
 * @Title: BaseOperation.java
 * @Description: 运算方法抽象类(即策略类, 定义了所有支持的算法的公共接口)
 * @Author: xj
 * @Date: 2018/9/1 14:59
 */
public abstract class BaseOperation {

    public abstract double getResult(double numberA, double numberB) throws Exception;
}

加法类
具体策略类,封装了具体的算法或行为

/**
 * @Title: OperationAdd.java
 * @Description:加法类
 * @Author: xj
 * @Date: 2018/9/1 15:02
 */
public class OperationAdd extends BaseOperation {

    @Override
    public double getResult(double numberA, double numberB) throws Exception {
        return numberA + numberB;
    }
}

减法类
具体策略类,封装了具体的算法或行为

/**
 * @Title: OperationSub.java
 * @Description: 减法类
 * @Author: xj
 * @Date: 2018/9/1 15:06
 */
public class OperationSub extends BaseOperation {

    @Override
    public double getResult(double numberA, double numberB) {
        return numberA - numberB;
    }
}

乘法类
具体策略类,封装了具体的算法或行为

package StrategyPattern.operation;

/**
 * @Title: OperationMul.java
 * @Description: 乘法类
 * @Author: xj
 * @Date: 2018/9/1 15:05
 */
public class OperationMul extends BaseOperation {

    @Override
    public double getResult(double numberA, double numberB) {
        return numberA * numberB;
    }
}

除法类
具体策略类,封装了具体的算法或行为

/**
 * @Title: OperationDiv.java
 * @Description: 除法类
 * @Author: xj
 * @Date: 2018/9/1 15:04
 */
public class OperationDiv extends BaseOperation {

    @Override
    public double getResult(double numberA, double numberB) throws Exception {
        if (numberB == 0) {
            throw new Exception("除数不能为0");
        }
        return numberA / numberB;
    }
}

运算方法上下文类
用一个子类来配置,维护一个对父类的引用

/**
 * @Title: OperationContext.java
 * @Description: 运算方法上下文类, 用一个子类来配置, 维护一个对父类的引用
 * @Author: xj
 * @Date: 2018/9/1 15:05
 */
public class OperationContext {

    private BaseOperation operation;

    public OperationContext(BaseOperation operation) {
        this.operation = operation;
    }

    public double getResult(double numberA, double numberB) throws Exception {
        return operation.getResult(numberA, numberB);
    }
}

测试类

/**
 * @Title: Test1.java
 * @Description: 测试类
 * @Author: xj
 * @Date: 2018/9/1 15:12
 */
public class Test1 {

    public static void main(String[] args) throws Exception {
        OperationContext context;
        context = new OperationContext(new OperationAdd());
        double resultAdd = context.getResult(20, 5); // 25.0
        System.out.println(resultAdd);

        context = new OperationContext(new OperationSub());
        double resultSub = context.getResult(20, 5); // 15.0
        System.out.println(resultSub);

        context = new OperationContext(new OperationMul());
        double resultMul = context.getResult(20, 5); // 100.0
        System.out.println(resultMul);

        context = new OperationContext(new OperationDiv());
        double resultDiv = context.getResult(20, 5); // 4.0
        System.out.println(resultDiv);
    }
}

以上就是策略模式的一个小例子


策略模式,需要手动判断使用哪个算法,因此我们可以跟简单工厂模式一起结合使用


四、策略模式结合简单工厂模式示例

运算方法工厂上下文类

/**
 * @Title: OperationFactoryContext.java
 * @Description: 运算方法工厂上下文类
 * @Author: xj
 * @Date: 2018/9/1 15:21
 */
public class OperationFactoryContext {

    private BaseOperation operation;

    public OperationFactoryContext(String type) {
        switch (type) {
            case "+": operation = new OperationAdd(); break;
            case "-": operation = new OperationSub(); break;
            case "*": operation = new OperationMul(); break;
            case "/": operation = new OperationDiv(); break;
            default: operation = null;
        }
    }

    public double getResult(double numberA, double numberB) throws Exception {
        return operation.getResult(numberA, numberB);
    }
}

测试类

/**
 * @Title: Test2.java
 * @Description: 测试类
 * @Author: xj
 * @Date: 2018/9/1 15:28
 */
public class Test2 {

    public static void main(String[] args) throws Exception {
        OperationFactoryContext context;
        context = new OperationFactoryContext("+");
        double resultAdd = context.getResult(20, 5); // 25.0
        System.out.println(resultAdd);

        context = new OperationFactoryContext("-");
        double resultSub = context.getResult(20, 5); // 15.0
        System.out.println(resultSub);

        context = new OperationFactoryContext("*");
        double resultMul = context.getResult(20, 5); // 100.0
        System.out.println(resultMul);

        context = new OperationFactoryContext("/");
        double resultDiv = context.getResult(20, 5); // 4.0
        System.out.println(resultDiv);
    }
}

以上就是策略模式结合简单工厂模式的一个小例子

posted @ 2018-09-01 18:19  GeneXu  阅读(60)  评论(0)    收藏  举报