定义:
定义一系列算法,将每个算法封装到具有公共接口的一系列策略类中,从而使它们可以相互替换,并让算法可以在不影响到客户端的情况下发生变化。
解决的问题:
使得客户端可以根据外部条件选择不同策略来解决不同问题
- 策略模式仅仅封装算法(包括添加 & 删除),但策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定
- 让算法和对象分开来,使得算法可以独立于使用它的客户而变化
uml类图:
模式组成:
- Context:环境类。用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据
- Strategy:抽象策略类。定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法
- ConcreteStrategy:具体策略类。以Strategy接口实现某具体算法
优点:
- 策略类之间可以自由切换
由于策略类都实现同一个接口,所以使它们之间可以自由切换。
- 易于扩展
增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“
- 避免使用多重条件选择语句(if else),充分体现面向对象设计思想
缺点:
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
- 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。
举个栗子:
定义抽象角色类
interface IStrategy{ public void show(); }
定义具体策略
class StrategyA implements IStrategy{ @Override public void show() { System.out.println("super model show"); } }
定义具体策略
class StrategyB implements IStrategy{ @Override public void show() { System.out.println(" magic show"); } }
定义环境类
class Context{ static IStrategy st; public static void show(String level){ switch(level){ case "vip": st=new StrategyA(); break; case "member": st=new StrategyB(); break; } st.show(); } }
客户端调用
public static void main(String[] args) { Context.show("vip"); }
输出