《Android原始碼設計模式解析與實戰》讀書筆記(七)
一、策略模式的簡介
1.1、定義
策略模式定義了一系列的演算法,並將每一個演算法封裝起來,而且使它們還可以相互替換。策略模式讓演算法獨立於使用它的客戶而獨立變化。
1.2、使用場景
- 針對同一型別問題的多種處理方式,僅僅是具體行為有差別時;
- 需要安全地封裝多種同一型別的操作時。
- 出現同一抽象類有多個子類,而又需要使用if-else或者switch-case來選擇具體子類時。
二、策略模式的簡單實現
示例:公交車和地鐵的價格計算方式是不一樣的,需要計算乘不同出行工具的成本,下面是第一版的程式碼:
public class PriceCalculator {
//公交車型別 private static final int BUS = 1;
//地鐵型別 private static final int SUBWAY = 2;
public static void main(String[] args) {
PriceCalculator calculator = new PriceCalculator();
System.out.println("坐16公里的公交車票價為:" + calculator.calculatePrice(16, BUS));
System.out.println("坐16公里的地鐵票價為:" + calculator.calculatePrice(16, SUBWAY));
} /** * 北京公交車,十公里之內一元錢,超過十公里之後每加一元錢可以乘5公里 * * @param km * @return */ private int busPrice(int km) {
//超過十公里的總距離 int extraTotal = km - 10;
//超過的距離是5公里的倍數 int extraFactor = extraTotal / 5;
//超過的距離對5公里取餘 int fraction = extraTotal % 5;
//價格計算 int price = 1 + extraFactor * 1;
return fraction >
0 ? ++price : price;
} /** * 6公里(含)內3元;6~12公里(含)4元;12~22公里(含)5元;
22~32公里(含)6元; * @param km * @return */ private int subwayPrice(int km) {
if (km <
= 6) {
return 3;
} else if (km >
6 &
&
km <
= 12) {
return 4;
} else if (km >
12 &
&
km <
= 22) {
return 5;
} else if (km >
22 &
&
km <
= 32) {
return 6;
} return 7;
} int calculatePrice(int km, int type) {
if (type == BUS) {
return busPrice(km);
} else if (type == SUBWAY) {
return subwayPrice(km);
} return 0;
}
}複製程式碼
輸出結果:
此時的程式碼已經比較混亂,各種if-else語句纏繞其中。當價格的計算方法變化時,需要直接修改這個類中的程式碼,很容易引入錯誤。這類程式碼必然是難以應對變化的,它會使得程式碼變得越來越臃腫,難以維護。
用策略模式對上述示例進行重構:
/** * 計算介面 */public interface CalculateStrategy {
/** * 按距離來計算價格 * @param km * @return */ int calculatePrice(int km);
}複製程式碼
//公交車價格計算策略public class BusStrategy implements CalculateStrategy {
/** * 北京公交車,十公里之內一元錢,超過十公里之後每加一元錢可以乘5公里 * @param km * @return */ @Override public int calculatePrice(int km) {
//超過十公里的總距離 int extraTotal = km - 10;
//超過的距離是5公里的倍數 int extraFactor = extraTotal / 5;
//超過的距離對5公里取餘 int fraction = extraTotal % 5;
//價格計算 int price = 1 + extraFactor * 1;
return fraction >
0 ? ++price : price;
}
}複製程式碼
public class SubwayStrategy implements CalculateStrategy {
@Override public int calculatePrice(int km) {
if (km <
= 6) {
return 3;
} else if (km >
6 &
&
km <
= 12) {
return 4;
} else if (km >
12 &
&
km <
= 22) {
return 5;
} else if (km >
22 &
&
km <
= 32) {
return 6;
} return 7;
}
}複製程式碼
再建立一個扮演Context角色的類
public class TranficCalculator {
public static void main(String[] args) {
TranficCalculator calculator = new TranficCalculator();
//設定計算策略 calculator.setStrategy(new BusStrategy());
//計算價格 System.out.println("坐16公里的公交車票價為:"+calculator.calculatePrice(16));
} CalculateStrategy mStrategy;
public void setStrategy(CalculateStrategy mStrategy) {
this.mStrategy = mStrategy;
} public int calculatePrice(int km) {
return mStrategy.calculatePrice(km);
}
}複製程式碼
這種方案在隱藏實現的同時,可擴充套件性變得很強。在簡化邏輯、結構的同時,增強了系統的可讀性、穩定性、可擴充套件性,這對於較為複雜的業務邏輯顯得更為直觀,擴充套件也更為方便。
三、總結
策略模式主要用來分離演算法,在相同的行為抽象下有不同的具體實現策略。這個模式很好地演示了開閉原則,也就是定義抽象,注入不同的實現,從而達到很好的可擴充套件性。
3.1、優點
- 結構清晰明瞭、使用簡單直觀;
- 耦合度相對而言較低,擴充套件方便;
- 操作封裝也更為徹底,資料更為安全。
3.2、缺點
- 隨著策略的增加,子類也會變得繁多。