策略模式

Posted 云聪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了策略模式相关的知识,希望对你有一定的参考价值。

策略模式定义了算法族,这些算法被分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。
这是《深入浅出设计模式》对策略模式的定义,这个定义说得很准确,但是书中的示例却举得不好,让我对策略模式的理解总是“一会儿感觉理解了,一会儿感觉没有理解”。直到看了《Effective Java》第二版第21条,用函数对象表示策略,才终于只是处于“感觉理解了”的状态了。根据自己的理解,写了下面这个例子,供大家参考:

package strategy;

public interface SortStrategy {  
    public <T extends Comparable<T>> void sort(T[] a);  
}
package strategy;

public class InsertSort implements SortStrategy {  

    @Override  
    public <T extends Comparable<T>> void sort(T[] a) {  
        // TODO Auto-generated method stub  
        int length = a.length;  
        for(int i = 0; i < length; i++) {  
            T key = a[i];  
            // 需要与key比较的元素的位置  
            int j = i - 1;  
            /** 
             * j >= 0保证a[j]存在; 
             * a[j].compareTo(key) > 0保证a[j] > key, a[j]的位置需要后移, 
             * 这时(a[j]后移之后,j自减1之前),j就是key的候选位置; 
             * 如果是因为j < 0而退出while循环的,说明子数组中没有小于key的元素, 
             * 也就是说,0是key的正确位置。 
             */  
            while (j >= 0 && a[j].compareTo(key) > 0) {  
                // 元素后移一个位置  
                a[j+1] = a[j];  
                // 需要比较的元素的位置前移  
                j--;  
            }  
            // j+1就是key的正确位置  
            a[j+1] = key;  
        }  

    }  

} 
package strategy;

import java.lang.reflect.Array;  

public class MergeSort implements SortStrategy {  

    @SuppressWarnings("unchecked")  
    private <T extends Comparable<T>> void merge(T[] a, int p, int q, int r) {  
        // 获得数组left的长度  
        int n1 = q - p + 1;  
        // 获得数组right的长度  
        int n2 = r - q;  
        // 创建数组left  
        T[] left = (T[]) Array.newInstance(a.getClass().getComponentType(), n1);  
        // 创建数组right  
        T[] right = (T[]) Array.newInstance(a.getClass().getComponentType(), n2);  
        // 把数组a的相应值赋给left  
        for(int i = 0; i < n1; i++){  
            left[i] = a[p + i];  
        }  
        // 把数组a的相应值赋给right  
        for(int i = 0; i < n2; i++){  
            right[i] = a[q + 1 + i];  
        }  
        // left数组当前待处理元素的位置  
        int i = 0;  
        // left结束标识  
        boolean endLeft = false;  
        // right数组当前待处理元素的位置  
        int j = 0;  
        // right结束标识  
        boolean engRight = false;  
        int k = p;  
        while(k <= r){  
            if (left[i].compareTo(right[j]) < 0) {  
                a[k] = left[i];  
                // 说明left的最后一个元素已被处理  
                if (i == (n1 - 1)) {  
                    endLeft = true;  
                    k++;  
                    break;  
                }  
                i++;  
            } else {  
                a[k] = right[j];  
                // 说明right的最后一个元素已被处理  
                if (j == (n2 - 1)) {  
                    engRight = true;  
                    k++;  
                    break;  
                }  
                j++;  
            }  
            k++;  
        }  
        // 把还没处理完的数组的剩余元素放进a中  
        if (endLeft) {  
            while(k <= r){  
                a[k] = right[j];  
                k++;  
                j++;  
            }  
        } else {  
            while(k <= r){  
                a[k] = left[i];  
                k++;  
                i++;  
            }  
        }  
    }  

    @Override  
    public <T extends Comparable<T>> void sort(T[] a) {  
        // TODO Auto-generated method stub  
        // 默认情况下,对数组从头到尾排序  
        int p = 0;  
        int r = a.length - 1;  
        sort(a, p, r);  

    }  

    private <T extends Comparable<T>> void sort(T[] a, int p, int r) {  
        // TODO Auto-generated method stub  
        if (p < r) {  
            int q = (p + r) / 2;  
            sort(a, p, q);  
            sort(a, q + 1, r);  
            merge(a, p, q, r);  
        }  

    }  

}  
package strategy;

public class Sort {
    public static SortStrategy INSERT_SORT = new InsertSort();
    public static SortStrategy MERGE_SORT = new MergeSort();

    public static <T extends Comparable<T>> void sort(T[] a, SortStrategy sortStrategy) {
        sortStrategy.sort(a);
    }
}
package strategy;

public class TestSort {
    public static void main(String[] args) {
        Integer[] a = new Integer[] {14, 2, 7, 9, 10};
        Sort.sort(a, Sort.INSERT_SORT);

        for (Integer integer : a) {
            System.out.print(integer + " ");
        }
    }
}

以上是关于策略模式的主要内容,如果未能解决你的问题,请参考以下文章

Redis实现分布式锁(设计模式应用实战)

用于从 cloudkit 检索单列的代码模式/片段

代码片-策略模式+工厂模式

代码片-策略模式+工厂模式

代码片-策略模式+工厂模式

代码片-策略模式+工厂模式