一. 定义:
策略模式:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换。
Context封装角色:它也叫上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化;
Strategy抽象策略角色:策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。(AlgorithmInterface即运算法则)
ConcreteStrategy具体策略角色:实现抽象策略的操作,该类含有具体的算法。
策略模式的重点是封装角色。它是借用了代理模式,它和代理模式的差别就是策略模式的封装角色和被封装的策略类不用是同一个接口。
public interface Strategy { //策略模式的运算法则 public void doSomething(); }
public class Context { //抽象策略 private Strategy strategy = null; //构造函数设置具体策略 public Context(Strategy strategy) { this.strategy = strategy; } //封装后的策略方法 public void doAnything() { this.strategy.doSomething(); } }
public class ConcerteStrategy1 implements Strategy { @Override public void doSomething() { System.out.println("具体策略1的运算法则"); } }
public class ConcerteStrategy2 implements Strategy { @Override public void doSomething() { System.out.println("具体策略2的运算法则"); } }
public class Client { public static void main(String[] args) { //声明一个具体的策略 Strategy strategy = new ConcerteStrategy1(); //声明上下文对象 Context context = new Context(strategy); //执行封装后的方法 context.doAnything(); } }
二. 策略模式优缺点:
策略模式优点:
-- 算法可以自由切换
-- 避免使用多重条件判断
-- 扩展性好
策略模式缺点:
-- 策略类数量增多
-- 所以策略类都需要对外暴露,暴露得越多以后的修改风险越大。
三. 策略模式的使用场景及注意事项
1.使用场景:
多个类只有在算法或行为上稍有不同的场景
算法需要自由切换的场景
需要屏蔽算法规则的场景
2.注意事项:
一个策略家族的具体策略数量超过4个就需要考虑使用混合模式避免类膨胀。
四. 解决策略模式的缺陷
增加一个映射配置文件,实现策略类的隐藏。使用枚举对策略类进行映射处理,避免高层模块直接访问策略类,同时由工厂方法模式根据映射产生策略对象。