定义了一系列的算法,把它们一个个封装起来,并且使它们可相互替换。策略模式使得算法独立于它的Client的变化而变化。策略模式可以帮助我们处理,当我们需要在不同的情况下使用不同的算法时的情况。策略模式适用于,许多类只有行为存在差异,或者需要使用一个算法的不同变体时。但是策略模式也有一些缺点,比如,Client必须了解不同的策略之前的差别,容易造成Context和Strategy之间的耦合,增加了对象的数量等。
策略模式的Strategy接口必须经过仔细设计,以支持子类可能实现的所有算法,因为如果基类接口功能不够强大,在修改或添加子类时可能会不得不修改基类接口,导致也需要修改其他子类。一般来讲,Strategy和Context接口就决定了该模式能支持的最大目标。
public interface Strategy {
public void algorithmInterface(int a, int b);
}
public class ConcreteStrategyA implements Strategy{
@Override
public void algorithmInterface(int a, int b) {
System.out.println(String.format("Using ConcreteStrategyA:(a+b=%d)", (a + b)));
}
}
public class ConcreteStrategyB implements Strategy{
@Override
public void algorithmInterface(int a, int b) {
System.out.println(String.format("Using ConcreteStrategyB:(a-b=%d)", (a - b)));
}
}
public class ConcreteStrategyC implements Strategy{
@Override
public void algorithmInterface(int a, int b) {
System.out.println(String.format("Using ConcreteStrategyC:(a*b=%d)", (a * b)));
}
}
public class Context {
private Strategy strategy = null;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void changeStrategy(Strategy strategy){
this.strategy = strategy;
}
public void contextInterface(int a, int b){
strategy.algorithmInterface(a, b);
}
}
public class Client {
@Test
public void test() {
Strategy stA = new ConcreteStrategyA();
Strategy stB = new ConcreteStrategyB();
Strategy stC = new ConcreteStrategyC();
int a = 1, b = 2;
Context context = new Context(stA);
context.contextInterface(a, b);
context.changeStrategy(stB);
context.contextInterface(a, b);
context.changeStrategy(stC);
context.contextInterface(a, b);
}
}
Strategy接口定义了所有算法应的统一规范,按照Strategy接口的定义方式,ConcreteStrategy实现了不同的算法。在Context中并没有实现各种算法,而是需要Client将各种Strategy注入其中,我们在之后只需要使用Context对象来调用各种不同的算法即可产生不同的结果。也就是说Strategy规定了算法的公共接口,ConcreteStrategy实现了各种不同的算法,而Context需要使用ConcreteStrategy对象来配置,并且定义了接口将数据传入Strategy对象。