前言: 本文仅作为第一次学习设计模式的参考和笔记。 初探策略模式:

策略模式:Strategy Pattern


又名:政策模式(Policy Pattern)。

原话:Define a family of algorithms , encapsulate each one , and make them interchangeable.

直译:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。

1. 定义:

一组算法继承同一接口,可以在需求下,进行互换。

2. 示例类图:

策略模式类图

3. 示例代码:
//抽象的策略角色:
instance Strategy{
    //策略模式的运算法则
    public void doSomeThing();
}

//具体策略角色:
class ConcreteStrategy1 implements Strategy {
    public void doSomeThing{
        //具体策略1的运算法则
    }
}
class ConcreteStrategy2 implements Strategy {
    public void doSomeThing{
        //具体策略2的运算法则
    }
}

//封装角色
class Context {
    //抽象策略
    private Strategy strategy = null;
    //构造函数设置具体策略
    public Context(Strategy _strategy){
        this.strategy = _strategy;
    }
    //封装后的策略方法
    public void doSomeThing(){
        this.strategy.doSomeThing();
    }
}

public class Client {
    public static void main(String[] args){
        //声明一个具体的策略
        Strategy strategy = new ConcreteStrategy1();
        //声明上下文对象
        Context context = new Context(strategy);
        //执行封装后的方法
        context.doSomeThing();
    }
}
4. 优点:
  • 算法可以自由切换
  • 避免使用多重条件判断
  • 拓展性好:添加一个策略直接实现接口,其他完全不用修改。
5. 缺点:
  • 策略类数量增多:复用性小
  • 所有的策略类都要对外暴露(用工厂模式/代理模式可以解决这个缺点)
6. 使用场景:
  • 多个类只有在算法或行为上稍有不同的场景
  • 算法需要自由切换的场景
  • 需要屏蔽算法规则的场景
7. 扩展:策略枚举
//策略枚举:
enum Calculator{
    //加法运算
    ADD("+"){
        public int exec(int a,int b){
            return a+b;
        }
    },
    //减法运算
    SUB("-"){
        public int exec(int a,int b){
            return a-b;
        }
    };
    String value = "";
    //定义成员值类型
    private Calculator(String _value){
        this.value = _value;
    }
    //获得枚举成员的值
    private String getValue(){
        return this.value;
    }
    //声明一个抽象函数
    public abstract int exec(int a , int b);
}

public class Client{
    public static void main(String[] args){
        //输入的两个参数是数字
        int a = Integer.parseInt(args[0]);
        String symbol = args[1];    //符号
        int b = Integer.parseInt(args[2]);
        System.out.println("输出的参数为:"+Arrays.toString(args));
        System.out.println("运算结果为:"+a+symbol+b+"="+Calculator.ADD.exec(a,b));
    }
}