策略模式:定义了一系列算法族,并将每一个算法封装起来,而且使他们可以互相替换。策略模式让算法独立于使用它的客户而独立变化。
问题:假设我们有一个类,提供为List排序功能,分别有选择使用快速排序,冒泡排序。
我们常使用的最普通的实现方式:
/** * 排序工具类 * @author PC * */ public class SortUtil { /** * 快速排序 */ public static final int TYPE_QUICK = 1; /** *冒泡排序 */ public static final int TYPE_MP = 2; /** * 排序 * @param list * @param type */ public static void sort(List<Integer> list,int type){ switch (type) { case TYPE_QUICK: sortQuick(list); break; case TYPE_MP: sortMP(list); break; } } /** * 快速排序 * @param list */ public static void sortQuick(List<Integer> list){ //TODO 快速排序实现 } /** * 冒泡排序 * @param list */ public static void sortMP(List<Integer> list){ //TODO 冒泡排序实现 } } 调用端: public class Client { public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); SortUtil.sort(list, SortUtil.TYPE_QUICK); } }是不是觉得实现的还可以,代码多清晰好看,又是静态常量,又是选择的,内部封装的多好,外部一个方法,选择一个常量TYPE就可以了,多牛逼。。我曾经也是这样写代码的。。
然而问题来了。。 我现在需要增加堆排序!!我还要增加插入排序!!你可能会说,那没事啊,多加几个方法实现,再加个type就可以了,外面看起来还是没变,用起来还是挺舒服的啊。
但是!还有更过分的,我现在不仅要排序整数了,我还要排序排序对象。。。对象?我去,排序对象可麻烦了,因为在这个对象来之前你根本不知道这个对象是何种结构,而且要咋样排序,那该肿么办呢? 还是老样子,抽象可变部分,具体使用哪种功能让具体的子类去实现,并且由调用端去选择。
定义顶层接口:
/** * 排序顶层接口 * 泛型:用于接收类型明确的各种类型。。。 * @author PC * * @param <T> */ public interface Sortor<T> { public void sort(List<T> list); } 优化SortUtil类: /** * 排序工具类 * @author PC * */ public class Sorts { /** * 排序 * @param list * @param type */ public static <T> void sort(List<T> list,Sortor<T> sortor){ sortor.sort(list); } } 实现一些基本的排序器: /** * 排序快速器 * @author PC * */ class Quick implements Sortor<Integer>{ public void sort(List<Integer> list) { //快速排序 } } /** * 冒泡排序器 * @author PC * */ class MP implements Sortor<Integer>{ public void sort(List<Integer> list) { //冒泡排序实现 } } 调用端: public class Client { public static void main(String[] args) { Sorts.sort(new ArrayList<Integer>(), new Quick()); } } 需要用什么排序,就new一个哪种排序的实现类进去就行了,当然这里可以给各种默认的排序器提供一个获取方式。这是需要为对象排序怎么办?
class Student{ String name; } /** * 对象比较器 * @author PC * */ class MySort implements Sortor<Student>{ public void sort(List<Student> list) { //自己实现对student的排序,比如按照name排序 } }自己实现Sortor接口,并定义排序规则,然后调用端:public class Client { public static void main(String[] args) { Sorts.sort(new ArrayList<Student>(), new MySort()); } } 没毛病吧,哈哈。大家可能会觉得是曾相识吧,我们java中的Arrays.sort就是这样实现的。以及我们经常使用的TreeSet传入比较器,我们来看看: class MyComparator implements Comparator<Student>{ public int compare(Student o1, Student o2) { return 0; } } 使用: public class Client { public static void main(String[] args) { TreeSet<Student> treeSet = new TreeSet<Student>(new MyComparator()); Collections.sort(new ArrayList<Student>(),new MyComparator()); } } 没毛病吧,和我们写的那一套东西一样吧。是的!