策略模式
1. 概念
策略模式是指定义一组算法,并把其封装到一个对象中,然后在运行时,可以灵活的使用其中的一个算法。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象,策略对象改变 context 对象的执行算法。
策略模式在Java标准库中应用非常广泛,以排序为例,对于Arrays.sort()
,如果我们想忽略大小写排序,就传入String::compareToIgnoreCase
,如果我们想倒序排序,就传入(s1, s2) -> -s1.compareTo(s2)
,这个比较两个元素大小的算法就是策略。
我们观察Arrays.sort(T[] a, Comparator<? super T> c)
这个排序方法,它在内部实现了TimSort排序,但是,排序算法在比较两个元素大小的时候,需要借助我们传入的Comparator
对象,才能完成比较。因此,这里的策略是指比较两个元素大小的策略,可以是忽略大小写比较,可以是倒序比较,也可以根据字符串长度比较。
因此,上述排序使用到了策略模式,它实际上指,在一个方法中,流程是确定的,但是,某些关键步骤的算法依赖调用方传入的策略,这样,传入不同的策略,即可获得不同的结果,大大增强了系统的灵活性。
2. 示例
我们将创建一个定义活动的 Strategy
接口和实现了 Strategy
接口的实体策略类。 Context
是一个使用了某种策略的类,同时客户端类 StrategyPatternDemo
使用 Context
和策略对象来演示 Context
在它所配置或使用的策略改变时的行为变化。

创建一个接口
public interface Strategy { public int doOperation(int num1, int num2); }
创建实现接口的实体类
public class OperationAdd implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 + num2; } }
public class OperationSubtract implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 - num2; } }
public class OperationMultiply implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 * num2; } }
创建
Context
类public class Context { private Strategy strategy; public Context(Strategy strategy){ this.strategy = strategy; } public int executeStrategy(int num1, int num2){ return strategy.doOperation(num1, num2); } }
使用
Context
来查看当它改变策略Strategy
时的行为变化public class StrategyPatternDemo { public static void main(String[] args) { Context context = new Context(new OperationAdd()); System.out.println("10 + 5 = " + context.executeStrategy(10, 5)); context = new Context(new OperationSubtract()); System.out.println("10 - 5 = " + context.executeStrategy(10, 5)); context = new Context(new OperationMultiply()); System.out.println("10 * 5 = " + context.executeStrategy(10, 5)); } }
执行程序,输出结果: 10 + 5 = 15 10 - 5 = 5 10 * 5 = 50