策略模式(Strategy Design Pattern)

栏目: 后端 · 发布时间: 5年前

内容简介:定义一系列算法,封装每个算法,并使它们可互换。策略模式允许算法独立于使用它的客户端。

目的

定义一系列算法,封装每个算法,并使它们可互换。策略模式允许算法独立于使用它的客户端。

解释

为了解释现实世界中的策略,让我们以软件开发人员为例。如果语言不是问题,我可能会要求开发人员为我编写一段代码来创建用户界面。一个开发者选择的语言是Java,所以他将用Swing开发UI。同时,另一个开发人员决定使用C。我不介意,我已经把如何编写UI的细节留给了开发人员,并且他们都应用了自己的策略。在任何阶段,开发人员都可以改变他们的策略,如果他们觉得有必要,可以选择使用不同的语言。所有这些都是关于动态变化的行为。

技术示例

1.策略模式的最佳示例之一是采用Comparator参数的 Collections.sort() 方法。基于Comparator接口的不同实现,对象将以不同的方式进行排序。

2.策略模式的另一个用途是以不同格式保存文件,运行各种 排序 算法或文件压缩。

3.要执行诸如加法,减法,除法和乘法等数学运算,我们需要决定在运行时执行哪个运算。

结构

策略模式(Strategy Design Pattern)

参与者

1.策略(Strategy)

  • 声明所有支持的算法共有的接口。 
  • context使用此接口来调用ConcreteStrategy定义的算法。

2.具体策略 ConcreteStrategy

  •  使用Strategy接口实现算法。

3.上下文 (Context)

  •  配置了ConcreteStrategy对象。
  •  维护对Strategy对象的引用。
  •  可以定义一个让Strategy访问其数据的接口。

合作

  • 策略和上下文交互以实现所选算法。当调用算法时,上下文可以将算法所需的所有数据传递给策略。或者,上下文可以将自己作为参数传递给策略操作。这使策略可以根据需要调用上下文。
  • 上下文将客户的请求转发给其策略。客户端通常创建一个具体的策略对象并将其传递给上下文;此后,客户端专门与上下文进行交互。通常有一系列具体的策略类供客户选择。

让我们看看它是如何在 Java 中运行的。

1.实现( 数学运算作为算法)

请参阅此实现的 结构图 ,并按照 结构图 创建组件 

第1步:创建一个类似Strategy.java的界面

<b>public</b> <b>interface</b> Strategy {
   <b>public</b> <b>int</b> doOperation(<b>int</b> num1, <b>int</b> num2);
}

第2步:创建实现相同接口的具体类。

OperationAdd.java

<b>public</b> <b>class</b> OperationAdd implements Strategy{
   @Override
   <b>public</b> <b>int</b> doOperation(<b>int</b> num1, <b>int</b> num2) {
      <b>return</b> num1 + num2;
   }
}

OperationSubstract.java

<b>public</b> <b>class</b> OperationSubstract implements Strategy{
   @Override
   <b>public</b> <b>int</b> doOperation(<b>int</b> num1, <b>int</b> num2) {
      <b>return</b> num1 - num2;
   }
}

OperationMultiply.java

<b>public</b> <b>class</b> OperationMultiply implements Strategy{
   @Override
   <b>public</b> <b>int</b> doOperation(<b>int</b> num1, <b>int</b> num2) {
      <b>return</b> num1 * num2;
   }
}

operationDevision.java

<b>public</b> <b>class</b> OperationDevision implements Strategy{
   @Override
   <b>public</b> <b>int</b> doOperation(<b>int</b> num1, <b>int</b> num2) {
      <b>return</b> (num1/num2);
   }
}

第3步:创建  上下文  类。

Context.java

<b>public</b> <b>class</b> Context {
   <b>private</b> Strategy strategy;

   <b>public</b> Context(Strategy strategy){
      <b>this</b>.strategy = strategy;
   }

   <b>public</b> <b>int</b> executeStrategy(<b>int</b> num1, <b>int</b> num2){
      <b>return</b> strategy.doOperation(num1, num2);
   }
}

第4步:使用  上下文  查看更改其策略时的行为更改  。

StrategyPatternDemo.java

<b>public</b> <b>class</b> StrategyPatternDemo {
   <b>public</b> <b>static</b> <b>void</b> main(String[] args) {
      Context context = <b>new</b> Context(<b>new</b> OperationAdd());  
      System.out.println(<font>"10 + 5 = "</font><font> + context.executeStrategy(10, 5));

      context = <b>new</b> Context(<b>new</b> OperationSubstract());  
      System.out.println(</font><font>"10 - 5 = "</font><font> + context.executeStrategy(10, 5));

      context = <b>new</b> Context(<b>new</b> OperationMultiply());  
      System.out.println(</font><font>"10 * 5 = "</font><font> + context.executeStrategy(10, 5));
   }
}
</font>

第5步:验证输出。

10 + 5 = 15
10 - 5 = 5
10 * 5 = 50

2.实施(文件压缩工具)

请参阅 此实现的 结构图 ,并按照 结构图 创建组件   让我们使用文件压缩 工具 的例子 - 我们创建zip或rar文件。首先,我们需要一个策略: 

<font><i>//Strategy Interface</i></font><font>
<b>public</b> <b>interface</b> CompressionStrategy {
  <b>public</b> <b>void</b> compressFiles(ArrayList<File> files);
}
</font>

我们需要提供两个实现,一个用于zip,一个用于rar

<b>public</b> <b>class</b> ZipCompressionStrategy implements CompressionStrategy {
  <b>public</b> <b>void</b> compressFiles(ArrayList<File> files) {
    <font><i>//using ZIP approach</i></font><font>
  }
}
</font>
<b>public</b> <b>class</b> RarCompressionStrategy implements CompressionStrategy {
  <b>public</b> <b>void</b> compressFiles(ArrayList<File> files) {
    <font><i>//using RAR approach</i></font><font>
  }
}
</font>

我们的上下文将为客户端提供压缩文件的方法。假设我们的应用程序中有一个首选项设置,用于设置要使用的压缩算法。我们可以使用Context中的setCompressionStrategy方法更改策略。

<b>public</b> <b>class</b> CompressionContext {
  <b>private</b> CompressionStrategy strategy;
  <font><i>//this can be set at runtime by the application preferences</i></font><font>
  <b>public</b> <b>void</b> setCompressionStrategy(CompressionStrategy strategy) {
    <b>this</b>.strategy = strategy;
  }
  
  </font><font><i>//use the strategy</i></font><font>
  <b>public</b> <b>void</b> createArchive(ArrayList<File> files) {
    strategy.compressFiles(files);
  }
}
</font>

很明显,所有客户端现在要做的就是将文件传递给CompressionContext。

<b>public</b> <b>class</b> Client {
  <b>public</b> <b>static</b> <b>void</b> main(String[] args) {
    CompressionContext ctx = <b>new</b> CompressionContext();
    <font><i>//we could assume context is already set by preferences</i></font><font>
    ctx.setCompressionStrategy(<b>new</b> ZipCompressionStrategy());
    </font><font><i>//get a list of files...</i></font><font>
    ctx.createArchive(fileList);
  }
}
</font>

适用场景

  • 许多相关类只在他们的行为上有所不同。策略模式提供了一种将类配置为多种行为之一的方法。
  • 你需要不同的算法变体。例如,您可以定义反映不同空间/时间权衡的算法。当这些变体作为算法的类层次结构实现时,可以使用策略模式。
  • 算法使用客户端不应该知道的数据。使用策略模式可避免暴露复杂的特定于算法的数据结构。
  • 一个类定义了许多行为,这些行为在其操作中显示为多个条件语句。而不是很多条件,将相关的条件分支移动到自己的Strategy类中。

以上所述就是小编给大家介绍的《策略模式(Strategy Design Pattern)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

B端产品经理必修课

B端产品经理必修课

李宽 / 电子工业出版社 / 2018-9 / 59

《B端产品经理必修课:从业务逻辑到产品构建全攻略》主要讲述了“单个产品管理流程”,以展示B 端产品经理的工作方法及B 端产品的设计方法。《B端产品经理必修课:从业务逻辑到产品构建全攻略》分为三个部分。第一部分主要讲述的是B 端产品经理的工作流程和定义(即单个产品管理流程),以及从事B 端产品经理的职业现状和规划,还包括设计B 端产品时需要了解的指导思想。第二部分是通过各个章节来讲述单个产品管理流程......一起来看看 《B端产品经理必修课》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具