策略模式
1.定义
一个类的行为或其算法可以在运行时进行更改。
策略模式通常有3种角色。
AbstractStrategy:抽象策略角色。策略,算法的抽象。
public interface AbstractStrategy {
/**
* 策略的行为,算法
*/
void operate();
}
Strategy:具体策略角色。实现抽象策略中定义的行为或算法。
public class StrategyOne implements AbstractStrategy {
@Override
public void operate() {
System.out.println("策略模式1的具体行为");
}
}
public class StrategyTwo implements AbstractStrategy {
@Override
public void operate() {
System.out.println("策略模式2的具体行为");
}
}
Context:上下文角色。封装具体的策略,屏蔽高层模块对策略,算法的直接访问。
public class Context {
/** 抽象策略 **/
private AbstractStrategy strategy;
/**
* 设置具体的策略
* @param strategy
*/
public void setStrategy(AbstractStrategy strategy) {
this.strategy = strategy;
}
/**
* 封装策略方法
*/
public void run() {
this.strategy.operate();
}
}
场景类
public class Client {
public static void main(String[] args) {
Context context = new Context();
/** 设置第一个策略 **/
context.setStrategy(new StrategyOne());
/** 执行第一个策略 **/
context.run();
/** 设置第二个策略 **/
context.setStrategy(new StrategyTwo());
/** 执行第二个策略 **/
context.run();
}
}
2.应用
2.1 优点
- 策略,算法可以自由的切换。
- 扩展性良好,只需要实现抽象策略即可。
2.2 缺点
- 当策略过多时,策略类的数量也会增加。
- 所有的策略类都需要对外暴露。高层模块必须知道有哪些策略才可以进行调用。
2.3 注意事项
当一个策略家族中策略类的数量超过4个时,需要考虑结合其它模式使用,解决策略类膨胀和对外暴露的问题。
3.扩展
输入三个参数(int, int, String),进行加减法运算,不考虑参数校验。
3.1 直接加减法
public class DirectCalculator {
private final static String ADD = "+";
private final static String SUB = "-";
public int calculate(int a, int b, String symbol) {
int result = 0;
if (ADD.equals(symbol)) {
result = this.add(a, b);
} else if (SUB.equals(symbol)) {
result = this.sub(a, b);
}
return result;
}
/**
* 加法 a + b
* @param a
* @param b
* @return
*/
private int add(int a, int b) {
return a + b;
}
/**
* 减法 a - b
* @param a
* @param b
* @return
*/
private int sub(int a, int b) {
return a - b;
}
}
3.2 策略模式
public interface Calculator {
/**
* 抽象计算方法
* @param a
* @param b
* @return
*/
int calculate(int a, int b);
}
public class AddCalculator implements Calculator {
/**
* 加法 a + b
* @param a
* @param b
* @return
*/
@Override
public int calculate(int a, int b) {
return a + b;
}
}
public class SubCalculator implements Calculator {
/**
* 减法 a - b
* @param a
* @param b
* @return
*/
@Override
public int calculate(int a, int b) {
return a - b;
}
}
public class CalculatorContext {
private Calculator calculator;
public CalculatorContext(Calculator calculator) {
this.calculator = calculator;
}
public void setCalculator(Calculator calculator) {
this.calculator = calculator;
}
public int calculate(int a, int b) {
return this.calculator.calculate(a, b);
}
}
3.3 策略枚举
public enum CalculatorStrategyEnum {
/** 加法运算 **/
ADD("+") {
@Override
public int calculate(int a, int b) {
return a + b;
}
},
/** 减法运算 **/
SUB("-") {
@Override
public int calculate(int a, int b) {
return a - b;
}
};
private String symbol = "";
CalculatorStrategyEnum(String symbol) {
this.symbol = symbol;
}
public String getSymbol() {
return this.symbol;
}
/**
* 声明一个计算的抽象方法
* @param a
* @param b
* @return
*/
public abstract int calculate(int a, int b);
}
public class Client {
public static void main(String[] args) {
System.out.println(CalculatorStrategyEnum.ADD.calculate(1, 2));
System.out.println(CalculatorStrategyEnum.SUB.calculate(5, 1));
}
}