策略模式:定义了一系列算法族,并将每一个算法封装起来,而且使他们可以互相替换。策略模式让算法独立于使用它的客户而独立变化。
问题:假设我们有一个类,提供为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就可以了,外面看起来还是没变,用起来还是挺舒服的啊。
但是!还有更过分的,我现在不仅要排序整数了,我还要排序排序对象。。。对象?我去,排序对象可麻烦了,因为在这个对象来之前你根本不知道这个对象是何种结构,而且要咋样排序,那该肿么办呢?
还是老样子,抽象可变部分,具体使用哪种功能让具体的子类去实现,并且由调用端去选择。
定义顶层接口:
/**
* 排序顶层接口
* 泛型:用于接收类型明确的各种类型。。。
* @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());
}
}
没毛病吧,和我们写的那一套东西一样吧。是的!