设计模式 | 挑战策略模式

1,103 阅读2分钟

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

一、概念

策略模式(Strategy Pattern)作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。 比如视频网站用户看视频的时,普通用户、会员、超级会员、限定会员“享受”的广告时间,选择的视频质量是大不相同。 简单点说,策略模式是指定义了算法家族、分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户,策略模式是一种对象行为模式。

所以策略模式的特征为:

  • 定义了一族算法(业务规则);
  • 封装了每个算法;
  • 这族的算法可互换代替(interchangeable)。

Strategy.png

二、代码模型

所谓策略模型,肯定是包含了一众多策略算法,我们先定义一个抽象的策略Strategy

public interface Strategy {
    /**
     * strategy details
     */
    void strategyImplementation();
}

针对这个抽象策略,我们提供一些不同的实现类。

DefaultStrategy


class DefaultStrategy implements Strategy {
​
    /**
     * strategy details
     */
    @Override
    public void strategyImplementation() {
        System.out.println("default strategy");
    }
}

AnotherStrategy

class AnotherStrategy implements Strategy {
​
    /**
     * strategy details
     */
    @Override
    public void strategyImplementation() {
        System.out.println("another strategy");
    }
}

策略算法我们准备好了,那客户端怎么方便使用它们呢?当然是用一个Context套住它。

public class Context {
​
    Strategy strategy = null;
​
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
​
    public void doStrategy() {
        strategy.strategyImplementation();
    }
​
}

具体客户端使用的方法。

    public static void main(String[] args) {
        final Context context = new Context(new DefaultStrategy());
        context.doStrategy();
        final Context anotherContext = new Context(new AnotherStrategy());
        anotherContext.doStrategy();
    }

往往我们在生产环境中不会这样使用,为啥呢?因为往往我们都是根据实际需求动态选择策略,而不是一次性执行多个策略。

修改一下客户端使用方式,通过获取一个策略点,来进行动态地分配策略。

    static void doStrategy(String strategyPoint){
        Context context;
        if(strategyPoint.equals("default")){
            context = new Context(new DefaultStrategy());
        }else if(strategyPoint.equals("another")){
            context = new Context(new AnotherStrategy());
        }else{
            throw new IllegalArgumentException("Unknown strategy");
        }
        context.doStrategy();
    }

可以很清楚地看到,如果后期策略不断的增加,这段逻辑也会不断地修改,那么怎么办呢,下一篇文章我们讲到如何使用工厂模式+策略模式优化这部分代码。

三、总结

那策略模式适合哪些应用场景呢?

  • 假如系统中有很多类,而它们的区别仅仅在于他们的行为不同。
  • 一个系统需要动态地在几种算法中选择一种。

策略模式强调的因为业务场景的动态变化,需要引入模式进行管理,如果本身你的算法极少发生改变,那确实没有必要引入策略模式,强行引入会增加代码量、逻辑的复杂度。
而且策略模式对于使用者来说也不是特别友好,因为它要选择不同的策略,所以它必须知道各个策略的差异性。