策略模式

Posted 被罚站的树

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了策略模式相关的知识,希望对你有一定的参考价值。

介绍


当我们有一组算法需要进行切换的时候可以采用策略模式。

类图关系


context:封装角色

它也叫上下文角色,起承上启下的封装作用,屏蔽高层模块对策略,算法的直接访问

Strategy:抽象策略角色

策略,算法家族的抽象,通常为接口,定义每个策略或算法必须具有的算法和属性。

ConcreteStratedy:具体策略角色

实现抽象策略中的操作,该类含有具体的算法

示例代码


抽象策略类

interface Strategy{
    //策略模式的运算法则
    public void doSomething();
}

具体策略类1

class ContreteStrategy1 implements Strategy{
    @Override
    public void doSomething(){
        System.out.println("具体策划类1的运算法则");
    }
}

具体策略类2

class ConcreteStragegy2 implements Strategy{
    @Override
    public void doSomething() {
        System.out.println("具体策略2的运算法则");
    }
}

上下文类

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

场景类

class Client{
    public static void main(String[] args) {
        String str = "策略1";
        Context context;
        //声明一个具体的策略
        Strategy strategy1 = new ContreteStrategy1();
        Strategy strategy2 =  new ConcreteStragegy2();
        //声明上下文对象
        if(str.equals("策略1"))
            context = new Context(strategy1);
        else
            context = new Context(strategy2);
        context.doAnything();
    }
}

场景类中根据不同情况选择不同的策略,最后执行策略类的方法。

总结


优点:算法可以自由切换,避免使用多重条件判断,扩展性良好

缺点:策略数量增多,所有的策略类向外暴露,违背迪米特法则

扩展

为了防止策略类扩展,可以使用枚举类处理

public enum Strategy{
    ADD("+"){
        public int exec(int a, int b){
            return a+b;
        }
    },
    SUB("-"){
        public int exec(int a, int b){
            return a-b;
        }
    };

    Strategy(String _value){
        this.value = _value;
    }

    public String getValue(){
        return this.value;
    }

    public abstract int exec(int a, int b);
}

 

以上是关于策略模式的主要内容,如果未能解决你的问题,请参考以下文章

Redis实现分布式锁(设计模式应用实战)

用于从 cloudkit 检索单列的代码模式/片段

代码片-策略模式+工厂模式

代码片-策略模式+工厂模式

代码片-策略模式+工厂模式

代码片-策略模式+工厂模式