1.TEMPLATE METHOD 泛型,也就是這個模式,是可以基於泛型的。 我們往往會有一些演算法,比如排序演算法。它的演算法部分,我可以把它放在一個基類裡面,這樣具體類型的比較可以放在子類裡面。 看如下冒泡排序演算法: 先看int的排序: 只要實現了比較和交換2個介面,就可以了。 在看看基於泛型的子類: ...
1.TEMPLATE METHOD
泛型,也就是這個模式,是可以基於泛型的。
我們往往會有一些演算法,比如排序演算法。它的演算法部分,我可以把它放在一個基類裡面,這樣具體類型的比較可以放在子類裡面。
看如下冒泡排序演算法:
package com.joyfulmath.agileexample.template.method; /** * @author deman.lu * @version on 2016-06-09 10:04 */ public abstract class BubbleSorter { private int operations = 0; protected int length = 0; protected int doSort() { operations = 0; if(length<=1) return operations; for(int nextToLast = length-2;nextToLast>=0;nextToLast--) for(int index = 0;index<=nextToLast;index++) { if(outOfOrder(index)) { swap(index); } } return operations; } protected abstract void swap(int index); protected abstract boolean outOfOrder(int index); }
先看int的排序:
package com.joyfulmath.agileexample.template.method; /** * @author deman.lu * @version on 2016-06-09 10:18 */ public class IntBubbleSorter extends BubbleSorter{ private int[] array = null; public int sort(int[] theArray) { array = theArray; length = theArray.length; return doSort(); } @Override protected void swap(int index) { int temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; } @Override protected boolean outOfOrder(int index) { return array[index]>array[index+1]; } }
只要實現了比較和交換2個介面,就可以了。
在看看基於泛型的子類:
package com.joyfulmath.agileexample.template.method; /** * @author deman.lu * @version on 2016-06-09 10:23 */ public class GenericBubbleSorter<T extends Comparable> extends BubbleSorter { private T[] array = null; public int sort(T[] theArray) { array = theArray; length = theArray.length; return doSort(); } @Override protected void swap(int index) { T temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; } @Override protected boolean outOfOrder(int index) { return array[index].compareTo(array[index+1])>0; } }
public class BubbleDemo { public static void action() { Integer[] array = new Integer[]{ 1,2,3,5,6,8,10,0,2,3 }; GenericBubbleSorter<Integer> intBubleSorter = new GenericBubbleSorter<>(); intBubleSorter.sort(array); for(int i=0;i<array.length;i++) { TraceLog.i(array[i].toString()); } } }
這樣就可以實現冒泡排序了。
敏捷開發的原則,就是不一定要使用設計模式,看情況,看需要。所以這裡可以說這個BubbleSorter有些多餘,直接GenericBubbleSorter使用,並實現排序演算法就可以,視具體情況而定。
但是有時候,我們希望把排序演算法和具體的使用者隔離開來,或者說我希望修改排序演算法,但不修改其他的代碼,這樣耦合就降低了。
2.STRATEGY 模式
關於策略模式的介紹,可以看我以前的博客:設計模式4---策略模式
這裡我們介紹冒泡排序的另一種模式。
public class BubbleSorter { private int operations = 0; protected int length = 0; private SortHandler itsSortHandle = null; public BubbleSorter(SortHandler itsSortHandle) { this.itsSortHandle = itsSortHandle; } public int sort(Object array) { itsSortHandle.setArray(array); length = itsSortHandle.length(); operations = 0; if (length <= 1) return operations; for (int nextToLast = length - 2; nextToLast >= 0; nextToLast--) for (int index = 0; index <= nextToLast; index++) { if (itsSortHandle.outOfOrder(index)) { itsSortHandle.swap(index); } operations++; } return operations; } }
這裡把排序演算法還是放在BubbleSorter里,他不知道誰要排序(SortHandler ),所以BubbleSorter & SortHandler 的實現類是 解耦的。
public class GenericSortHandle<T extends Comparable> implements SortHandler { private T[] array = null; @Override public void swap(int index) { T temp = array[index]; array[index] = array[index+1]; array[index+1] = temp; } @Override public boolean outOfOrder(int index) { return array[index].compareTo(array[index+1])>0; } @Override public int length() { return array.length; } @Override public void setArray(Object array) { this.array = (T[]) array; } }
這裡可以做2個替換,一個是排序演算法,一個是排序的素材。這就是策略模式,
演算法可以替換,演算法使用的環境是一致的。
public class BubbleDemo2 { public static void action() { Integer[] array = new Integer[]{ 1,2,3,5,6,8,10,0,2,3 }; GenericSortHandle<Integer> intBubleSorter = new GenericSortHandle<>(); BubbleSorter bubbleSorter = new BubbleSorter(intBubleSorter); bubbleSorter.sort(array); for(int i=0;i<array.length;i++) { TraceLog.i(array[i].toString()); } } }
還是那句話,設計模式的使用,根據具體情況而定,如果需求,環境發生變化,就有可能從沒有設計模式,到重構代碼,運用設計模式。
這就是敏捷開發,根據需求變化而變換設計模式的使用,包括不使用任何模式!
參考:
《敏捷軟體開發》 Robert C. Martin