Strategy策略模式是屬於設計模式中對象行爲型模式,主要是定義一系列的算法,把這些算法一個個封裝成單獨的類.我們達到了在運行期間,可以自由切換算法的目的。實際整個Strategy的核心部分就是抽象類(或者接口)的使用,使用Strategy模式可以在用戶需要變化時,修改量很少,而且快速.一直有點糊塗的地方就是factory&strategy,實際上Strategy和Factory有一定的類似,Strategy相對簡單容易理解,並且可以在運行時刻自由切換,Factory重點是用來創建對象。
設計模式就是把簡單的東西複雜化,但是有理有據,看你將來在那個方向做擴展,那麼就會在那個方向上複雜化,等等,農場生小母牛,那類與類之間的關係太簡單了,感受不到系統之間的精妙的結構的樂趣.設計模式可以讓你感受到這纔是面向對象的樂趣精華所在!
設計模式筆記上的例子比較好,這裏拿過來爲以後的理解做鋪墊。
TextStrategy是個抽象類,內含抽象方法:replace,linuxstrategy,windowsstrategy繼承這個抽象類,同時各自實現方法replace,textCharChange調用textStrategy類中的replace方法進行使用,
TextStrategy抽象類的結構:
public abstract classTextStrategy {
protected String text;
public TextStrategy(String text) {
this.text = text;
}
public abstract String replace();
}
Linux的實現策略:
public classLinuxStrategy extends TextStrategy {
publicLinuxStrategy(String text) {//構造方法
super(text);
}
public String replace() {//實現的具體方法,這纔是核心
preOperation();
System.out.println(text =text.replaceAll("@r@n", "@n"));
postOperation();
return text;
} }
Windows實現策略:
public classWindowsStrategy extends TextStrategy {
public WindowsStrategy(String text) {
super(text);
}
public String replace() {
startOperation();
System.out.println(text =text.replaceAll("@n", "@r@n"));
endOperation();
return text;
}}
整合在一起使用的類:
public classTextCharChange {
public static voidreplace(TextStrategy strategy) {//傳策略的參數,直接調用,這兒很巧妙!!
strategy.replace();
} }
測試類:
public class Main {
public static void main(String[] args) {
String linuxText = "This is a test text!!@n Oh! LineReturn!!@n";
String windowsText = "This is atest text!!@r@n Oh! Line Return@r@n";
TextCharChange.replace( new WindowsStrategy(linuxText));//直接調用就行!
System.out.println();
TextCharChange.replace( newLinuxStrategy(windowsText));
}}
strategy模式的結構圖,三個具體策略的實現類,一個抽象類或接口,另外一個整合使用的類,直接調用整合後的類即可~~
以上是strategy模式筆記比較簡單的用法,但是看sp學習的話,馬老師給出了一個很複雜的例子,有點迷糊,沒具體操作。。下次再寫吧,或者就不寫了,其實也很簡單,他的流程是這樣的:
首先用一般的sort方法,想着sort的複用而讓需要排序的類:cat,dag實現comparable接口,實現comparTo方法,通過這個方法對這個類的兩個對象比較大小,爲了實現對同一類的不同屬性的大小的比較,而對每個類生成多個比較策略類:CatHeightComparator,CatWeightComparator,這兩個比較策略使用時可以隨時調用。
分析了下sp中講到的例子,對cat對象比較大小,總共有兩個接口:comparable,comparator,其中comparable中方法爲:compareTo(0),comparator方法:compare(0,0),cat實現了comparable接口,實現compareTo()方法時,使用了compartor.compare()方法,及動態調用需要用到的比較策略:heighe,or weighte比較策略。HeightCompare,WeightCompare都實現了compartor接口,實現了compare方法。dataSorter類對數組中的所有對象進行sort操作。test是測試類。
具體代碼如下:
兩個接口的就省了,寫cat的實現:
public class Catimplements java.lang.Comparable<Cat> {
privateint height;
privateint weight;
//privateComparator comparator = new CatHeightComparator();
privatejava.util.Comparator<Cat> comparator = new CatHeightComparator();//此處已經賦值了,不如第一個例子中的給的動態性強
public Cat(Comparator comparator, int height, int weight) {//這樣就可以了。。
super();
this.comparator = comparator;
this.height = height;
this.weight = weight;
}
@Override
publicString toString() {//便於對象的輸出,若沒有的話,只會輸出對象在內存中的引用,是一串引用代碼;
returnheight + "|" + weight;}
@Override
publicint compareTo(Cat o) {//調用comparator的compare方法,這裏如上一個例子中的textChartChange中的replace方法一樣,但是此處調用不很靈活
return comparator.compare(this, o);//可以再爲對像初始化時,傳一個比較器接口,然後進行比較~
}}HeightCompare實現:weightCompare省掉。
public classCatHeightComparator implements java.util.Comparator<Cat> {
@Override
publicint compare(Cat o1, Cat o2) {//真正比較策略的實現,將方法封裝成類,方便動態調用而不用該代碼;
Catc1 = (Cat)o1;
Catc2 = (Cat)o2;
if(c1.getHeight()> c2.getHeight()) return 1;
elseif(c1.getHeight() < c2.getHeight()) return -1;
return0;
}}
DataSort實現:
public classDataSorter {
public static voidsort(Object[] a) {
for(inti=a.length; i>0; i--) {
for(intj=0; j<i-1; j++) {
Comparableo1 = (Comparable)a[j];
Comparableo2 = (Comparable)a[j+1];
if(o1.compareTo(o2)== 1) {//真正用的地方!實際上,compareTo方法調用了cat內的comparetor對象的compare方法;
swap(a,j , j+1);//工具方法
}}}}
privatestatic void swap(Object[] a, int x, int y) {//注意參數的傳遞,此處要有數組a ,不然起不到換位置的作用!
Objecttemp = a[x];
a[x]= a[y];
a[y]= temp;}
}
Test類實現:
public class Test {
publicstatic void main(String[] args) {
Cat[] c = { new Cat(new CatWeightComparator(), 1, 2),//動態傳比較的屬性值過來,這樣就可以了!
new Cat(new CatWeightComparator(), 27, 1),
new Cat(new CatWeightComparator(), 22, 3) };
DataSorter.sort(a);//直接調用dataSorter的sort方法,sort中調用comparable對象的compareTo方法,compareTo方法實際上調用的是comparable對象中comparetor對象的compare()方法,所以真正實現在comparetor實現類的compare方法中!
DataSorter.p(a);//打印出結果
}}
這個比上面那個例子複雜在:cat本身也是一個實現了comparable接口的類,這樣就跟compartor有點混淆了!其實真正的含義有兩點:
1.實現comparable對象的比較,並且做到datasort sortor方法的可重用性;
2.對同一comparable對象的不同比較方法的實現,並且用動態調用的方式使用;(當然這裏面沒有例子以做的好,因爲compartor對象是寫死在cat類裏的,最好的是在使用時,通過參數傳過來!)
3.與State一樣,例子中完美的面向對象的思維,用TextCharChange完美的把接口及其實現封裝起來,用的時候直接提供TextCharChange就行!贊一個!!而且方法名稱都一樣:replace.不會像後面那個例子那樣容易混淆!當然後面的例子也有他的原因,因爲他是要封裝整個DataSorter類及其sorter方法達到最好的複用性,所以首先要對外提供一個comparable的接口的參數傳遞,使得實現這個接口的所有的類都能調用這個方法進行sort,然後就涉及到,實現類可以調用方法進行比較了,但是真正的比較過程與簡單的數據類型又不相同,因爲是類的比較,有會考慮比較那個屬性?爲了提供更好的多態或者擴展性,就要對外提供一個很比較方法的策略參數的傳值:CatWeightCompartor()類實現了對重量的比較的策略,所以傳遞這個類的對象可以實現這種比較策略,同理,相同的策略是要實現於統一的接口的,才能保證被接受這個參數的方法使用!所以,catweightcompartor實現了compartor接口!
所以,仔細分析才知道,實際上是有兩層策略(sort,compareTo),每一層的使用都會用到接口.sort爲了實現對comparable的對象的比較,comparTo爲了實現對同一對象的多種不同的比較方式!