《Android源碼設計模式解析與實戰》讀書筆記(七)php
策略模式定義了一系列的算法,並將每個算法封裝起來,並且使它們還能夠相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。設計模式
示例:公交車和地鐵的價格計算方式是不同的,須要計算乘不一樣出行工具的成本,下面是初版的代碼:安全
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;
}
}
複製代碼
輸出結果:bash
此時的代碼已經比較混亂,各類if-else語句纏繞其中。當價格的計算方法變化時,須要直接修改這個類中的代碼,很容易引入錯誤。 這類代碼必然是難以應對變化的,它會使得代碼變得愈來愈臃腫,難以維護。微信
用策略模式對上述示例進行重構:ide
/**
* 計算接口
*/
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);
}
}
複製代碼
這種方案在隱藏實現的同時,可擴展性變得很強。在簡化邏輯、結構的同時,加強了系統的可讀性、穩定性、可擴展性,這對於較爲複雜的業務邏輯顯得更爲直觀,擴展也更爲方便。ui
策略模式主要用來分離算法,在相同的行爲抽象下有不一樣的具體實現策略。這個模式很好地演示了開閉原則,也就是定義抽象,注入不一樣的實現,從而達到很好的可擴展性。this