内容简介:定义一系列算法,封装每个算法,并使它们可互换。策略模式允许算法独立于使用它的客户端。
目的
定义一系列算法,封装每个算法,并使它们可互换。策略模式允许算法独立于使用它的客户端。
解释
为了解释现实世界中的策略,让我们以软件开发人员为例。如果语言不是问题,我可能会要求开发人员为我编写一段代码来创建用户界面。一个开发者选择的语言是Java,所以他将用Swing开发UI。同时,另一个开发人员决定使用C。我不介意,我已经把如何编写UI的细节留给了开发人员,并且他们都应用了自己的策略。在任何阶段,开发人员都可以改变他们的策略,如果他们觉得有必要,可以选择使用不同的语言。所有这些都是关于动态变化的行为。
技术示例
1.策略模式的最佳示例之一是采用Comparator参数的 Collections.sort() 方法。基于Comparator接口的不同实现,对象将以不同的方式进行排序。
2.策略模式的另一个用途是以不同格式保存文件,运行各种 排序 算法或文件压缩。
3.要执行诸如加法,减法,除法和乘法等数学运算,我们需要决定在运行时执行哪个运算。
结构
参与者
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)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
疯狂Java讲义
李刚 / 电子工业出版社 / 2008-10 / 99.00元
《疯狂Java讲义》2000年至今,Java语言一直是应用最广的开发语言,并拥有最广泛的开发人群。如今,Java已经不再简单地是一门语言,它更像一个完整的体系,一个系统的开发平台。更甚至,它被延伸成一种开源精神。 《疯狂Java讲义》深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编......一起来看看 《疯狂Java讲义》 这本书的介绍吧!