1. 程式人生 > >設計模式-策略模式(結合JDK原始碼)

設計模式-策略模式(結合JDK原始碼)

策略模式:定義了一系列演算法族,並將每一個演算法封裝起來,而且使他們可以互相替換。策略模式讓演算法獨立於使用它的客戶而獨立變化。

問題:假設我們有一個類,提供為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());
	}
	
}

沒毛病吧,和我們寫的那一套東西一樣吧。是的!