在日常開發(fā)過程中時常需要用到設(shè)計模式,但是設(shè)計模式有23種缸废,如何將這些設(shè)計模式了然于胸并且能在實際開發(fā)過程中應(yīng)用得得心應(yīng)手呢?和我一起跟著《Android源碼設(shè)計模式解析與實戰(zhàn)》一書邊學(xué)邊應(yīng)用吧忌警!
設(shè)計模式系列文章
- Android 設(shè)計模式之單例模式
- Android 設(shè)計模式之Builder模式
- Android 設(shè)計模式之觀察者模式
- Android 設(shè)計模式之代理模式
- Android 設(shè)計模式之裝飾模式
- Android 設(shè)計模式之外觀模式
- Android 設(shè)計模式之原型模式
- Android 設(shè)計模式之工廠方法模式
- Android 設(shè)計模式之適配器模式
- Android 設(shè)計模式之橋接模式
- Android 設(shè)計模式之狀態(tài)模式
- Android 設(shè)計模式之面向?qū)ο蟮牧笤瓌t
今天我們要講的是策略模式
定義
策略模式定義了一系列算法营搅,并將每一個算法封裝起來,而且使它們可以相互替換矫限。策略模式讓算法獨立于使用它的客戶端而獨立變化
使用場景
- 針對同一類型問題的多種處理方式哺哼,僅僅是具體行為有差別時
- 需要安全地封裝多種同一類型的操作時
- 出現(xiàn)同一抽象類有多個子類,而又需要if-else或者switch-case來選擇具體的子類時
使用例子
- Android中屬性動畫的時間差值器分為線性差值器叼风、加速減速差值器等取董,這些差值器里面就用到了策略模式來隔離不同的動畫速率計算算法
實現(xiàn)
3大角色
- 用來操作策略的上下文環(huán)境
- 策略的抽象
- 具體的策略實現(xiàn)
實現(xiàn)的要點
- 將不同策略的相同的行為抽象到抽象策略中
- 具體的策略實現(xiàn)不同的算法
- 上下文環(huán)境根據(jù)需要注入需要的策略,并把相應(yīng)的操作委托給注入的策略處理
實現(xiàn)方式
下面我們以計算不同交通工具的車費來簡單看看策略模式的實現(xiàn)
- 首先抽象出計算車費的操作咬扇,因為不同的策略最后都會計算車費并返回結(jié)果
public interface CalculateStragety {
/**
* 根據(jù)公里數(shù)計算價格
*
* @param km 公里數(shù)
* @return 價格
*/
int calculatePrice(int km);
}
- 然后我們分別實現(xiàn)具體的策略甲葬,比如計算公交車的車費的策略
public class BusStragety implements CalculateStragety {
/**
* 十公里之內(nèi)一元,超過十公里每加一元錢可以坐5公里
* @param km 公里數(shù)
* @return 公交車車費
*/
@Override
public int calculatePrice(int km) {
//超過十公里的總距離
int extraTotal = km - 10;
// 超過的距離是5公里的倍數(shù)
int extraFactor = extraTotal / 5;
//超過的距離對5公里取余
int fraction = extraTotal % 5;
//價格計算
int price = 1 + extraFactor * 1 ;
return fraction > 0 ? ++price : price;
}
}
- 再加一個出租車的車費計算策略
public class TaxiStragety implements CalculateStragety {
/**
* 出租車車費為每公里2元
* @param km 公里數(shù)
* @return 出租車車費
*/
@Override
public int calculatePrice(int km) {
return km * 2;
}
}
- 然后我們看看怎么根據(jù)需要注入不同的策略懈贺,并把具體的計算委托給注入的策略
public class TrafficCalculator {
public static void main(String[] args) {
TrafficCalculator trafficCalculator = new TrafficCalculator();
trafficCalculator.setCalculateStragety(new BusStragety());
trafficCalculator.calculatePrice(66);
}
CalculateStragety mCalculateStragety;
/**
* 根據(jù)需要注入相應(yīng)的策略
*
* @param calculateStragety 注入的策略
*/
public void setCalculateStragety(CalculateStragety calculateStragety) {
mCalculateStragety = calculateStragety;
}
/**
* 把具體的計算委托給注入的策略
*
* @param km 公里數(shù)
* @return 車費
*/
private int calculatePrice(int km) {
return mCalculateStragety.calculatePrice(km);
}
}
- 在上面的例子中我們通過在TrafficCalculator中動態(tài)注入計算公交車車費的策略來計算公交車費经窖,當(dāng)然我們也可以計算出租車費坡垫,只需要把注入的策略改為出租車車費計算策略就可以了。
- 以上就是策略模式的簡單實現(xiàn)了画侣。
策略模式和代理模式
- 策略模式和代理模式在應(yīng)用情景上有點相似冰悠,都是處理有多種實現(xiàn)方式或是有多種情況需要考慮的情況,而且都是通過抽象提取各個子類的共同行為配乱。但是2種模式還是有很多不同之處溉卓。
- 首先代理模式有代理類,而策略模式?jīng)]有搬泥。
- 代理模式把對子類的選擇封裝在了代理類中桑寨,并通過代理類對外提供服務(wù);而策略模式則是通過動態(tài)注入的方式來讓客戶端選擇需要的策略
- 策略模式更側(cè)重于策略或是算法的封裝隔離忿檩;而代理模式更側(cè)重于通過代理類提供代理服務(wù)
- 最后尉尾,2者都有個缺點,就是隨著策略的增加或是要考慮的情況增多燥透,子類也會變得越來越多
總結(jié)
- 策略模式主要用來分離算法沙咏,在相同的行為抽象下有不同的具體實現(xiàn)策略。
- 策略模式很好地展示了開閉原則班套,也就是定義抽象肢藐,注入不同的實現(xiàn),從而達(dá)到很好的擴(kuò)展性
- 當(dāng)我們在實現(xiàn)一個功能時遇到很多if-else或是switch-case的時候就可以考慮下這里是不是可以用策略模式了
源碼地址:https://github.com/snowdream1314/DesignPatternsExamples
歡迎關(guān)注我的微信公眾號吱韭,期待與你一起學(xué)習(xí)吆豹,一起交流,一起成長杉女!