策略模式。在理论的我的项目开发中,这个模式也比拟罕用。最常见的利用场景是,利用它来防止简短的 if-else 或 switch 分支判断。不过,它的作用还不止如此。它也能够像模板模式那样,提供框架的扩大点等等。对于策略模式。本篇咱们解说策略模式的原理和实现,以及如何用它来防止分支判断逻辑。后续我会通过一个具体的例子,来具体解说策略模式的利用场景以及真正的设计用意。话不多说,进入主题

策略模式的原理与实现

策略模式能够使算法的变动独立于应用它们的客户端(这里的客户端代指应用算法的代码)。咱们晓得,工厂模式是解耦对象的创立和应用,观察者模式是解耦观察者和被观察者。策略模式跟两者相似,也能起到解耦的作用,不过,它解耦的是策略的定义、创立、应用这三局部。能够先浏览上面一篇文章放慢对策略模式的了解

设计模式行为型:策略模式(StrategyPattern)

接下来,我就具体讲讲一个残缺的策略模式应该蕴含的这三个局部。

策略的定义

策略类的定义比较简单,蕴含一个策略接口和一组实现这个接口的策略类。因为所有的策略类都实现雷同的接口,所以,客户端代码基于接口而非实现编程,能够灵便地替换不同的策略。示例代码如下所示:

策略的创立

因为策略模式会蕴含一组策略,在应用它们的时候,个别会通过类型(type)来判断创立哪个策略来应用。为了封装创立逻辑,咱们须要对客户端代码屏蔽创立细节。咱们能够把依据 type 创立策略的逻辑抽离进去,放到工厂类中。示例代码如下所示

一般来讲,如果策略类是无状态的,不蕴含成员变量,只是纯正的算法实现,这样的策略对象是能够被共享应用的,不须要在每次调用 getStrategy() 的时候,都创立一个新的策略对象。针对这种状况,咱们能够应用下面这种工厂类的实现形式,当时创立好每个策略对象,缓存到工厂类中,用的时候间接返回。

相同,如果策略类是有状态的,依据业务场景的须要,咱们心愿每次从工厂办法中,取得的都是新创建的策略对象,而不是缓存好可共享的策略对象,那咱们就须要依照如下形式来实现策略工厂类。

策略模式的应用

刚刚讲了策略的定义和创立,当初,咱们再来看一下,策略的应用。咱们晓得,策略模式蕴含一组可选策略,客户端代码个别如何确定应用哪个策略呢?最常见的是运行时动静确定应用哪种策略,这也是策略模式最典型的利用场景。这里的“运行时动静”指的是,咱们当时并不知道会应用哪个策略,而是在程序运行期间,依据配置、用户输出、计算结果等这些不确定因素,动静决定应用哪种策略。接下来,咱们通过一个例子来解释一下。

从下面的代码中,咱们也能够看出,“非运行时动静确定”,也就是第二个 Application 中的应用形式,并不能施展策略模式的劣势。在这种利用场景下,策略模式实际上进化成了“面向对象的多态个性”或“基于接口而非实现编程准则”。

如何利用策略模式防止分支判断

实际上,可能移除分支判断逻辑的模式不仅仅有策略模式,前面咱们要讲的状态模式也能够。对于应用哪种模式,具体还要看利用场景来定。策略模式实用于依据不同类型的动静,决定应用哪种策略这样一种利用场景。咱们先通过一个例子来看下,if-else 或 switch-case 分支判断逻辑是如何产生的。具体的代码如下所示。在这个例子中,咱们没有应用策略模式,而是将策略的定义、创立、应用间接耦合在一起。

如何来移除掉分支判断逻辑呢?那策略模式就派上用场了。咱们应用策略模式对下面的代码重构,将不同类型订单的打折策略设计成策略类,并由工厂类来负责创立策略对象。具体的代码如下所示:

重构之后的代码就没有了 if-else 分支判断语句了。实际上,这得益于策略工厂类。在工厂类中,咱们用 Map 来缓存策略,依据 type 间接从 Map 中获取对应的策略,从而防止 if-else 分支判断逻辑。等前面讲到应用状态模式来防止分支判断逻辑的时候,你会发现,它们应用的是同样的套路。实质上都是借助“查表法”,依据 type 查表(代码中的 strategies 就是表)代替依据 type 分支判断。然而,如果业务场景须要每次都创立不同的策略对象,咱们就要用另外一种工厂类的实现形式了。具体的代码如下所示:

总结

策略模式定义一族算法类,将每个算法别离封装起来,让它们能够相互替换。策略模式能够使算法的变动独立于应用它们的客户端(这里的客户端代指应用算法的代码)。策略模式用来解耦策略的定义、创立、应用。实际上,一个残缺的策略模式就是由这三个局部组成的。策略类的定义比较简单,蕴含一个策略接口和一组实现这个接口的策略类。策略的创立由工厂类来实现,封装策略创立的细节。策略模式蕴含一组策略可选,客户端代码如何抉择应用哪个策略,有两种确定办法:编译时动态确定和运行时动静确定。其中,“运行时动静确定”才是策略模式最典型的利用场景。除此之外,咱们还能够通过策略模式来移除 if-else 分支判断。实际上,这得益于策略工厂类,更实质上点讲,是借助“查表法”,依据 type 查表代替依据 type 分支判断。