阅读 94

行为型模式 —— 策略模式

什么是策略模式

策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数。

策略模式定义和封装了一系列的算法,它们是可以相互替换的,也就是说它们具有共性,而它们的共性就体现在策略接口的行为上,另外为了达到最后一句话的目的,也就是说让算法独立于使用它的客户而独立变化,我们需要让客户端依赖于策略接口。

一种很简单的解释,在我们的开发过程中,经常会遇到大量的 if...else 或者 switch...case 语句,当这些语句在开发中只是为了起到分流作用,这些分流和业务逻辑无关,那么这个时候就可以考虑用策略模式

策略模式的结构

 

这个模式涉及到三个角色:

  • 上下文环境(Context)角色:持有一个Strategy的引用。

  • 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

  • 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为

策略模式的应用场景

举一个例子,商场搞促销--打8折,满200送50,满1000送礼物,这种促销就是策略。

再举一个例子,dota里面的战术,玩命四保一,三伪核体系,推进体系,大招流体系等,这些战术都是一种策略。

应用场景:

1、 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。

2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。

3、 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

策略模式的实现

Strategy类,定义所有支持的算法的公共接口

//Strategy类,定义所有支持的算法的公共接口 public abstract class Strategy {     //算法方法     public abstract void algorithmInterface(); } 复制代码

ConcreteStrategy,封装了具体的算法或行为,继承于Strategy

//算法A class ConcreteStrategyA extends Strategy {     @Override     public void algorithmInterface() {         System.out.println("算法A的实现");     } } //算法B class ConcreteStrategyB extends Strategy{     @Override     public void algorithmInterface() {         System.out.println("算法B的实现");     } } //算法C class ConcreteStrategyC extends Strategy {     @Override     public void algorithmInterface() {         System.out.println("算法C的实现");     } } 复制代码

Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用

//Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用 public class Context {     private Strategy strategy;          public context(Strategy strategy) {         this.strategy = strategy;     }          //上下文接口     public void contextInterface() {         strategy.algorithmInterface();     } } 复制代码

客户端代码

public static void main(String[] args) {     Context context;     context = new Context(new ConcreteStrategyA());     context.contextInterface();     context = new Context(new ConcreteStrategyB());     context.contextInterface();     context = new Context(new ConcreteStrategyC());     context.contextInterface(); } 复制代码

策略模式和简单工厂模式的结合

改造后的Context

public class Context {     private Strategy strategy = null;          public Context(String type) {         if ("A".equals(type)) {             ConcreteStrategyA a = new ConcreteStrategyA();             strategy = a;         } else if ("B".equals(type)) {             ConcreteStrategyB b = new ConcreteStrategyB();             strategy = b;         } else if ("C".equals(type)) {             ConcreteStrategyC c = new ConcreteStrategyC();             strategy = c;         }     }          //上下文接口     public void ContextInterface()     {         strategy.algorithmInterface();     } } 复制代码

改造后的客户端代码

public static void main(String[] args) {     Context context = new Context("A");     context.contextInterface();          Context context = new Context("B");     context.contextInterface();          Context context = new Context("C");     context.contextInterface(); } 复制代码

对比下改造前后的区别不难看出,改造前客户端需要认识两个类,Context和ConcreteStrategy。而策略模式和简单工厂模式结合后,客户端只需要认识一个类Context,降低了耦合性。

策略模式的优缺点

优点:

  • 1、结构清晰,把策略分离成一个个单独的类「替换了传统的 if else」

  • 2、代码耦合度降低,安全性提高「各个策略的细节被屏蔽」

缺点:

  • 1、客户端必须要知道所有的策略类,否则你不知道该使用那个策略,所以策略模式适用于提前知道所有策略的情况下

  • 2、策略类数量增多(每一个策略类复用性很小,如果需要增加算法,就只能新增类)

总结

策略模式,实质就是封装了一些算法,让算法可以互相替换,用户可以自由选择这些算法进行操作。策略模式本身理解起来没什么难点,但是在实际应用中其本身主要结合工厂模式一起使用。


作者:Recluse
链接:https://juejin.cn/post/7022574577997856775


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐