定义:
准备了一组策略(算法),将算法封装起来,他们继承同一个接口或者抽象类,保证了他们可以替换。
并且,这种替换是不需要客户端来参与的。策略模式在设计模式中算是比较简单的,所以经常与工厂模式等其他的设计模式一起使用。
结构:
Context:上下文,引用了Strategy对象,负责算法的调用。
Strategy:一个接口或者抽象类,定义了所有策略实现的公共接口。
ConcreteStrategy:策略模式中具体的策略实现类,这些策略实现类实现了或者继承了Strategy。
UML:
Demo:
Strategy类:
public interface Strategy { public void say(); }
ConcreteStrategy类:
(作为Strategy的实现类,有多种策略(算法))
public class StrategyImpl01 implements Strategy { @Override public void say() { System.out.println("策略一"); } }
public class StrategyImpl02 implements Strategy { @Override public void say() { System.out.println("策略02"); } }
Context:
public class Context { Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void getContext() { strategy.say(); } }
Client:
//客户端代码 public class Client { public static void main(String[] args) { Strategy strategyImpl01 = new StrategyImpl01(); Context con = new Context(strategyImpl01); con.getContext(); Strategy strategyImpl02 = new StrategyImpl02(); Context con02 = new Context(strategyImpl02); con02.getContext(); } }
分析:
通过上面的Demo我们可以看出,如果还想增加策略3策略4等,我们不需要改变原来的类,只需要实现策略实现类的公共接口,
这样完全匹配了我们所说的开放-封闭原则。但是也存在缺点,客户端必须知道每种策略实现类到底做了什么,因为是客户端在调用它,所以必须是客户端必须了解其实现。
为了解决上面的问题我们决定采取和简单工厂模式结合的方式进行二次实现。
Context与简单工厂模式的结合:
Context:
public class Context { Strategy strategy = null; public void getContext(String arg) { switch (arg) { case "1": strategy = new StrategyImpl01(); break; case "2": strategy = new StrategyImpl02(); break; } strategy.say(); } }
client:
//客户端代码 public class Client { public static void main(String[] args) { Context context = new Context(); context.getContext("1"); context.getContext("2"); } }
经过与简单工厂模式的结合,客户端现在传入的参数就是字符串了。而对象的实例交给了Context。
策略模式是一个很简单的模式,经常与其他的设计模式一起使用。我们自己可以探讨更多的结合方式。