思路
在開發中,我們會遇到多個算法或者策略,來實現不同的行爲。我們根據環境和需求要實現不同的策略活着好算法。比如說,對對象的排序,一個對象有多個屬性,我們定義一個算法,根據這個對象的某個屬性來排序,假如有一天需求變更,根據這個屬性的另外一個屬性來排序。那麼我們可能我們設計好的算法也要進行變更,這顯然擴展性不好,不利於維護。
策略
在實際開發中,我們需要把算法和對象分開來。讓對象自身具備某個比較的實現,而我們自己設計的算法不再需要進行變更,這顯然使我們剛加希望的實現。讓程序按照我們的策略進行實現,而不用更改我們的算法,讓他們可以互相轉換。
模擬JAVA中的Comparable和Comparator的策略
package com.strategy;
public interface Comparable {
public int compareTo(Object o);
}
----------
//Comparator
package com.strategy;
public interface Comparator<T> {
int compare(T o,T j);
}
----------
//策略比較
package com.strategy;
public class HeightComparetor implements Comparator<Cat>{
public int compare(Cat o, Cat j) {
if(o.getHeight() > j.getHeight()) return 1;
if(o.getHeight() < j.getHeight()) return -1;
return 0;
}
}
----------
//Cat類
package com.strategy;
public class Cat implements Comparable{
private int height;
private int width;
//高度比較器
HeightComparetor comparetor = new HeightComparetor();
public Cat(int height, int width) {
super();
this.height = height;
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
@Override
public int compareTo(Object o) {
//這是之前採用的compareTo比較,而後採用高度比較器的策略模式,對於想用其他進行比較,只要在做Conparator的實現即可,而程序不用整個更改
/*Cat cat = (Cat)o;
if(this.getHeight() > cat.getHeight()) return 1;
if(this.getHeight() < cat.getHeight() ) return -1;*/
return comparetor.compare(this, (Cat)o);
}
@Override
public String toString() {
return "Cat [height=" + height + ", width=" + width + "]";
}
}
----------
//算法
package com.strategy;
public class Sorter {
//在這裏,我們的算法不需要更改
public static void sort(Cat[] a) {
for(int i = a.length;i > 0;i--){
for(int j =0; j < i - 1;j++){
Comparable co = a[j];
Comparable to = a[j+1];
if(co.compareTo(to) == 1){
swap(a,j,j+1);
}
}
}
}
private static void swap(Cat[] a, int i, int j) {
// TODO Auto-generated method stub
Cat temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void p(Cat[] a) {
for(int i = 0;i < a.length;i++){
System.out.print(a[i]+" ");
}
System.out.println();
}
}
----------
public static void main(String[] args) {
Cat[] a = {new Cat(3,2),new Cat(2,5)};
Sorter.sort(a);
Sorter.p(a);
}
----------
//Console
Cat [height=2, width=5] Cat [height=3, width=2]
優缺點
優點:我們的程序的算法重用性提高,只需要不同的策略實現就可以實現我們算法的互相轉換。在開發中,隨着一系列行爲的堆砌,不同的行爲又具備不同的特點,這一點上我們的算法總不能因爲行爲的增加而去爲每個行爲都設計一個算法吧。在一定情況下,也減輕了if else的出現,我們可以選擇不同的實現來爲算法匹配。
缺點:不同的行爲就要實現不同的策略,就意味着我們的程序會有很多的策略,而我們在使用的時候,對於客戶而言可能不知道某個策略的具體實現,同時也會把策略暴露在別人面前。而同時,我們的策略是按照我們定義的相同的接口實現的,而有時簡單的策略 的初始化,我們可能並不用到全部,而裏面某些參數卻已經初始化的,這顯然增加了通信開銷。而一旦存在這種問題,就要讓接口和策略進行緊耦合。
總結
右上面的模擬可以看見,策略模式的好處是,我們程序中的算法不需要進行更改,只需要對對象的某種策略進行比較,並且不影響算法的情況下,依然可以運行下去。,這就是策略模式