← 返回首页
设计模式基础教程(三十一)
发表时间:2021-08-30 17:46:24
策略模式

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