定義
策略模式(Strategy Pattern)中湃缎,一個(gè)類的行為或其算法可以在運(yùn)行時(shí)更改犀填。這種類型的設(shè)計(jì)模式屬于行為型模式
從定義中來(lái)看,策略模式的目標(biāo)是優(yōu)化類的行為選擇嗓违,將選擇行為和行為本身實(shí)現(xiàn)細(xì)節(jié)拆分九巡,達(dá)到選擇行為只控制流程,比如你要從A地到達(dá)B地蹂季,現(xiàn)在你有三種交通方式冕广,汽車(chē),自行車(chē)偿洁,火車(chē)撒汉。三種方式的耗時(shí),路線選擇都不一樣涕滋。如果采取策略模式來(lái)描述這個(gè)場(chǎng)景睬辐,則選擇何種交通方式就是在控制流程,而具體的流程細(xì)節(jié)是由單獨(dú)的行為本身實(shí)現(xiàn)何吝。
實(shí)例
public interface IntOpt {
public int doOpt(int num, int num2);
}
public class Add implements IntOpt {
@Override
public int doOpt(int num, int num2) {
return num + num2;
}
}
public class Multiply implements IntOpt {
@Override
public int doOpt(int num, int num2) {
return num * num2;
}
}
public class IntOptContext {
private IntOpt mIntOpt;
public IntOptContext(IntOpt intOpt){
this.mIntOpt = intOpt;
}
public int doOpt(int num, int nums){
if (mIntOpt != null) {
return mIntOpt.doOpt(num, nums);
}
return 0;
}
}
上述接口描述了四則運(yùn)算中的加法和乘法溉委,IntOptContext屬于策略的包裝類,加上該類可以給當(dāng)前框架充當(dāng)中間層爱榕,以至于有改動(dòng)的時(shí)候不用去修改客戶端代碼和策略實(shí)現(xiàn)瓣喊,如果不用該包裝,直接使用選擇的策略類來(lái)操作也是可以的黔酥。如果是單個(gè)算法實(shí)現(xiàn)藻三,也可以采用策略枚舉
public enum IntOptEnum {
ADD("+"){
@Override
public int doOpt(int num, int nums) {
return num + nums;
}
},
SUB("-"){
@Override
public int doOpt(int num, int nums) {
return num - nums;
}
};
String symbol;
private IntOptEnum(String symbol){
this.symbol = symbol;
}
public String getSymbol(){
return symbol;
}
public abstract int doOpt(int num, int nums);
}
總結(jié)
優(yōu)點(diǎn): 1洪橘、算法可以自由切換。 2棵帽、避免使用多重條件判斷熄求。 3、擴(kuò)展性良好逗概。
缺點(diǎn): 1弟晚、策略類會(huì)增多。 2逾苫、所有策略類都需要對(duì)外暴露卿城。
使用場(chǎng)景: 1、如果在一個(gè)系統(tǒng)里面有許多類铅搓,它們之間的區(qū)別僅在于它們的行為瑟押,那么使用策略模式可以動(dòng)態(tài)地讓一個(gè)對(duì)象在許多行為中選擇一種行為。 2星掰、一個(gè)系統(tǒng)需要?jiǎng)討B(tài)地在幾種算法中選擇一種多望。 3、如果一個(gè)對(duì)象有很多的行為氢烘,如果不用恰當(dāng)?shù)哪J交惩担@些行為就只好使用多重的條件選擇語(yǔ)句來(lái)實(shí)現(xiàn)。
注意事項(xiàng):如果一個(gè)系統(tǒng)的策略多于四個(gè)威始,就需要考慮使用混合模式枢纠,解決策略類膨脹的問(wèn)題像街。