2.2策略模式(5.9)
來源:程序員人生 發布時間:2014-09-28 07:37:15 閱讀次數:3148次
某種程度上,策略模式不值得一提,因為學習和理解它,其難度系數為0。不就是一個類層次的問題嗎。
所以,我們添加一點內容:方法對象化――將方法封裝為類型。
另外,從重構分支結構的角度看,策略模式與[1.3.2工廠方法模式(3.3)]和[3.2狀態模式(5.8)]是三胞胎。
1.父類定義接口,子類給出實現
外出旅游時,可以在多種不同的出行方式中選擇,如坐汽車/火車/飛機、騎自行車或步行。海關對不同的商品按照不同的稅率征收關稅……做事情的方式即策略或政策。在源代碼中,一個方法體常常被稱為一個算法,故封裝做事情方式的一個方法體,被稱為一個具體的策略。
策略模式以類層次定義和封裝算法集:父類定義接口,子類給出實現。【策略模式(Strategy Pattern):定義一系列算法類,將每一個算法封裝起來,并讓它們可以相互替換,策略模式讓算法獨立于使用它的客戶而變化,也稱為政策模式(Policy)。】
如【編程導論?11 排序】介紹了各種各樣的排序算法:選擇、插入和交換排序等。為了方便地測試各種算法,抽象類algorithm.sorting.IntSort封裝了抽象方法int[] sort(int[] arr),各種排序算法被設計成IntSort的子類。當然,IntSort除了包括策略,還可以提供了工具方法:如public static void swap(int[] arr ,int one, int two)――交換數組的兩個元素。
從封裝算法集的角度看,策略模式就是設計一個類層次。因而,學習和理解它,其難度系數為0。策略模式僅僅簡單地使用了多態技術。正因為策略模式僅僅簡單地使用了多態技術,因而策略模式成為其他模式常用的一個基本技術。也可以說,策略模式沒有技術含量。
2. 將策略從環境類中分離出來
還是以排序為例,
package method.strategy;
public class Context{
public void test(String s,int i,int j,int[] array){
if(s == "選擇") m1(i,j);
if(s == "插入") m2(array);
if(s == "交換") m3(array,i);
}
private void m1(int i,int j){}
private void m2(int[] array){}
private void m3(int[] array,int i){}
}
如果按照分支結構測試各種算法,在可能增加分支的場合該代碼不遵循OCP。顯然的解決方案是,設計MyStrategy的abstract方法
m(int i,int j,int[] array)封裝各種算法m1、m2、m3。在實際編程中,原來的m1()、m2()、m3()
可能需要各種不同的參數。因此設計抽象方法m()時,在保證返回值類型確定的前提下,m()必須能夠保證所有具體的策略類能夠獲得它需要的所有數據,因而在定義m()的接口時,它的參數列表是具體的策略類所需數據的最大集合。最大集合意味著寧可多不可少――某些具體策略類可以不使用參數列表提供的數據,但是不可使得某些具體策略類缺乏需要的數據。當然,僅就排序而言,參數情況簡單。
package method.strategy;
public interface MyStrategy{
public abstract int[] sort(int[] arr);
}// MyStrategy的子類型,略
注意,我們由于擁有依賴注入工具tips.IoC,因而代碼
package method.strategy;
import tips.IoC;
public class Context{
private MyStrategy s;
//依賴注入
public void setStrategy(MyStrategy s){
this.s=s;
}
public static void test(int[] arr){
MyStrategy st =(MyStrategy)IoC.getObject("插入");
int[] array = st.sort(arr);
}
}
如果要畫出策略模式的結構圖/UML圖,僅需要畫出了Context與MyStrategy兩者。
學習設計模式時,絕大多數情況下,我會忽略抽象類型如MyStrategy的子類型。一方面,子類型是必須有的,代碼大家自己寫;另一方面,通過IoC工具,Context不需要知道MyStrategy的子類型,因而,不畫出各子類型不影響讀者對該模式的理解。
策略模式的基本內容,就這么一點。
3.
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈