1.策略模式
完成一项任务,往往可以有多种不同的方式,每一种方式称为一个策略,我们可以根据环境或者条件的不同选择不同的策略来完成该项任务。
在软件开发中也常常遇到类似的情况,实现某一个功能有多个途径,此时可以使用一种设计模式来使得系统可以灵活地选择解决途径,也能够方便地增加新的解决途径。

策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。策略模式是一种对象行为型模式。
策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
2.实例
某系统提供了一个用于对数组数据进行操作的类,该类封装了对数组的常见操作,如查找数组元素、对数组元素进行排序等。现以排序操作为例,使用策略模式设计该数组操作类,使得客户端可以动态地更换排序算法,可以根据需要选择冒泡排序或选择排序或插入排序,也能够灵活地增加新的排序算法。

项目结构图如下:

定义排序接口
public interface Sort {
int[] sort(int[] arr);
}
冒泡排序
public class BubbleSort implements Sort {
@Override
public int[] sort(int[] arr) {
int len=arr.length;
for(int i=0;i<len;i++){
for(int j=i+1;j<len;j++){
int temp;
if(arr[i]>arr[j]){
temp=arr[j];
arr[j]=arr[i];
arr[i]=temp;
}
}
}
System.out.println("冒泡排序");
return arr;
}
}
选择排序
public class SelectionSort implements Sort {
public int[] sort(int arr[]) {
int len = arr.length;
int temp;
for (int i = 0; i < len; i++) {
temp = arr[i];
int j;
int samllestLocation = i;
for (j = i + 1; j < len; j++) {
if (arr[j] < temp) {
temp = arr[j];
samllestLocation = j;
}
}
arr[samllestLocation] = arr[i];
arr[i] = temp;
}
System.out.println("选择排序");
return arr;
}
}
插入排序
public class InsertionSort implements Sort {
public int[] sort(int arr[]) {
int len = arr.length;
for (int i = 1; i < len; i++) {
int j;
int temp = arr[i];
for (j = i; j > 0; j--) {
if (arr[j - 1] > temp) {
arr[j] = arr[j - 1];
} else
break;
}
arr[j] = temp;
}
System.out.println("插入排序");
return arr;
}
}
快速排序
public class QuickSort implements Sort {
@Override
public int[] sort(int[] arr) {
System.out.println("快速排序");
sort(arr, 0, arr.length - 1);
return arr;
}
public void sort(int arr[], int p, int r) {
int q = 0;
if (p < r) {
q = partition(arr, p, r);
sort(arr, p, q - 1);
sort(arr, q + 1, r);
}
}
public int partition(int[] a, int p, int r) {
int x = a[r];
int j = p - 1;
for (int i = p; i <= r - 1; i++) {
if (a[i] <= x) {
j++;
swap(a, j, i);
}
}
swap(a, j + 1, r);
return j + 1;
}
public void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
排序处理类
public class ArrayHandler {
private Sort sortObj;
public int[] sort(int arr[])
{
sortObj.sort(arr);
return arr;
}
public void setSortObj(Sort sortObj) {
this.sortObj = sortObj;
}
}
XML解析工具类
public class XMLUtil {
// 该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
public static Object getBean() {
try {
// 创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder
.parse(XMLUtil.class .getClassLoader().getResourceAsStream("config.xml"));
// 获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("className");
String className = nl.item(0).getTextContent();
// 通过类名生成实例对象并将其返回
Class c = Class.forName(className);
Object obj = c.newInstance();
return obj;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
配置文档
<?xml version="1.0"?>
<config>
<className>com.simoniu.domain.BubbleSort</className>
</config>
测试类
public class Client {
public static void main(String args[]) {
int arr[] = {10, 4, 6, 17,12, 52, 33, 18, 7, 10, 9};
int result[];
ArrayHandler ah = new ArrayHandler();
Sort sort;
sort = (Sort) XMLUtil.getBean();
ah.setSortObj(sort); //设置具体策略
result = ah.sort(arr);
for (int i = 0; i < result.length; i++) {
System.out.print(result[i] + " ");
}
}
}
运行结果:
冒泡排序
4 6 7 9 10 10 12 17 18 33 52