設計模式-策略模式(結合JDK原始碼)
阿新 • • 發佈:2019-02-14
策略模式:定義了一系列演算法族,並將每一個演算法封裝起來,而且使他們可以互相替換。策略模式讓演算法獨立於使用它的客戶而獨立變化。
問題:假設我們有一個類,提供為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());
}
}
沒毛病吧,和我們寫的那一套東西一樣吧。是的!