策略设计模式是Java API库中常见的模式之一。这与另一种设计模式非常相似,即状态设计模式。本文通过一个简单举例介绍,其是如何在Java中实现的。
概述
策略模式也称为政策模式。它被归类为行为软件设计模式,其的重点是在对象之间找到一种灵活的通信模式。它有助于在运行对象之间建立灵活的通信。
策略模式
策略模式的基本思想是在类的小层次扩展中组合一组操作。与策略相关的对象决定在给定的情况下使用哪种算法。例如,它使我们能够在运行时交换算法的实现细节,而不需要重写。这个构思与依赖注入的实现模式向呼应,因为它还允许在测试期间交换执行,例如在测试代码中执行模拟的实现。
它类似于状态设计模式,它是封装上下文对象状态的对象。策略设计模式中的一个对象类似地封装了一个算法的实现,并且可以在运行时根据需要和事件进行交换。
在Java API库中,java.awt.Container组件是使用此模式的一个示例。在这里,LayoutManager充当策略对象。诸如BorderLayout, FlowLayout, 和 GridLayout等类实现接口布局管理器。执行的类定义一个名为addLayoutComponent()的方法。这个方法中的定义决定了逻辑,或者组件在容器对象中的布局方式。例如,流布局将它们从左到右排列,而borderlayout将它们排列成名为“中心”、“北”、“东”、“南”、“西”的部分。容器类包含称为LayoutManager对象的策略对象。因为接口包含类的对象引用,该类可执行接口,所以策略对象可以随时引用执行的类。
策略模式的使用
它基本上是从公共基类继承的类集合。它有相同的基本结构和共同的功能,但区别在于它的使用方式。可以说,它按照所采用的策略运行。策略模式通过提供运行时灵活性来增强功能。与其他类似的模式(如状态和命令)不同,这种灵活性可以通过创建一个代理类来加以利用,该类在运行时控制特定策略的选择。
执行策略模式
下面是这个模式的快速实现。这个构思非常简单,然而它在挑选出所需的执行很有效并根据需要进行交换。没什么好笑的,接口和类的层次结构创建了一种呈现,一种在代码中使用的策略。
在此,它使我们能够使用排序接口编写代码,并且我们想要排序的代码不需要涉及用于排序的算法。通过编程接口和满足特定执行的类结构,我们可以根据需要使用接口,并在需要时立即更改策略。从某种意义上说,这个构思是可扩展的,稍后我们可以添加更多的执行。任何针对接口编写的代码都不会更改,但可以使用新的执行。
package org.mano.example;
public interface Sort {
int [] sort(int[] nos);
}
package org.mano.example;
public class BubbleSort implements Sort{
@Override
public int [] sort(int[] nos) {
System.out.println("\n--- BUBBLE SORT strategy
in action---\n");
int n = nos.length;
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (nos[j] > nos[j+1])
{
int tmp = nos[j];
nos[j] = nos[j+1];
nos[j+1] = tmp;
}
return nos;
}
}
package org.mano.example;
public class SelectionSort implements Sort{
@Override
public int [] sort(int [] nos) {
System.out.println("\n--- SELECTION SORT strategy
in action ---\n");
int n = nos.length;
for (int i = 0; i < n-1; i++)
{
int mindex = i;
for (int j = i+1; j < n; j++)
if (nos[j] < nos[mindex])
mindex = j;
int temp = nos[mindex];
nos[mindex] = nos[i];
nos[i] = temp;
}
return nos;
}
}
package org.mano.example;
public class ShellSort implements Sort {
@Override
public int [] sort(int[] nos) {
System.out.println("\n--- SHELL SORT strategy
in action ---\n");
int n = nos.length;
for (int part = n/2; part > 0; part /= 2)
{
for (int i = part; i < n; i += 1)
{
int temp = nos[i];
int j;
for (j = i; j >= part && nos[j - part] >
temp; j -= part) nos[j] = nos[j - part];
nos[j] = temp;
}
}
return nos;
}
}
package org.mano.example;
import java.util.Random;
public class SortingApp {
private Sort sortStrategy;
public SortingApp(Sort sort){
this.sortStrategy = sort;
}
public int [] sort(int[] data){
return sortStrategy.sort(data);
}
public void changeStrategy(Sort anotherStrategy){
sortStrategy = anotherStrategy;
}
public void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i
System.out.println();
}
public static int [] getDummyData(){
Random r = new Random();
int [] data = new int [10];
for (int i=0;i<10;i++)
data[i] = r.nextInt(100);
return data;
}
public static void main(String[] args){
SortingApp app = new SortingApp(new BubbleSort());
app.printArray(app.sort(getDummyData()));
app.changeStrategy(new SelectionSort());
app.printArray(app.sort(getDummyData()));
app.changeStrategy(new ShellSort());
app.printArray(app.sort(getDummyData()));
}
}
Output
--- BUBBLE SORT strategy in action---
5 15 22 38 41 45 56 72 72 97
--- SELECTION SORT strategy in action ---
42 47 52 55 60 76 79 82 86 96
--- SHELL SORT strategy in action ---
11 13 19 24 27 33 47 72 72 88
结论
策略模式使我们能够将有关要使用的实现策略的决策推迟到运行之时。当我们使用Spring框架将XML用作配置文件来构造对象及其依赖时,其会在运行时被读取。这种模式的主要优点是它可使用执行之间的动态变化,而不需要重新编译。