什么是策略模式
在策略模式(Strategy Pattern)中尸曼,一個類的行為或其算法可以在運行時更改。這種類型的設(shè)計模式屬于行為型模式控轿。
在策略模式中解幽,我們創(chuàng)建表示各種策略的對象和一個行為隨著策略對象改變而改變的 context 對象。策略對象改變 context 對象的執(zhí)行算法片部。
其思想是針對一組算法,將每一種算法都封裝到具有共同接口的獨立的類中廊鸥,從而是它們可以相互替換辖所。策略模式的最大特點是使得算法可以在不影響客戶端的情況下發(fā)生變化缘回,從而改變不同的功能。
簡單解釋
參照大話設(shè)計模酥宴、菜鳥教程拙寡。1授滓、商場收費為例,無論原價收取肆糕、打折收取還是滿300減50般堆,這些都是一個一個的策略。2诚啃、外出旅行淮摔,無論選擇坐巴士、騎自行車或選擇飛機出生绍申,這都是一個一個的策略噩咪。這些策略都是隨時可能互相替換,且互相之前并不影響极阅。
- 優(yōu)點
1胃碾、算法可以自由切換筋搏。 2仆百、避免使用多重條件判斷。 3奔脐、擴展性良好俄周。 - 缺點
1、策略類會增多髓迎。 2峦朗、所有策略類都需要對外暴露。
代碼解釋
參照大話設(shè)計模式中的商場促銷排龄,商場促銷分別是打折波势、滿減或者原價收費,我們可以把計算收費做為抽象方法提取出來;
1尺铣、定義抽象類拴曲,將計算費用方法抽象;
/**
* 抽象算法類凛忿,定義算法
*/
public abstract class Strategy {
/**
* 算法方法
*/
public abstract Double getMoney(Double money);
}
2澈灼、分別定義子類,正常收費店溢、打折收費叁熔、滿減收費三個子類,繼承抽象類床牧,實現(xiàn)具體方法
/**
* 正常收費
*/
public class StrategyNormal extends Strategy {
@Override
public Double getMoney(Double money) {
System.out.println("正常收費");
return money;
}
}
/**
* 打折收費
*/
public class StrategyRebate extends Strategy {
private Double rebate;
/**
* 實例化時者疤,傳入具體打折參數(shù),例:打八折叠赦,則傳入0.8
* @param rebate
*/
public StrategyRebate(Double rebate){
this.rebate=rebate;
}
@Override
public Double getMoney(Double money) {
return money*rebate;
}
}
/**
* 滿減收費 滿300減100
*/
public class StrategyReturn extends Strategy {
private Double moneyCondition;
private Double moneyReturn;
/**
* 傳滿足條件后,減多少費用
* @param moneyCondition 條件
* @param moneyReturn 減免條件
*/
public StrategyReturn(Double moneyCondition,Double moneyReturn){
this.moneyCondition=moneyCondition;
this.moneyReturn=moneyReturn;
}
@Override
public Double getMoney(Double money) {
if(money>=this.moneyCondition){
return money-this.moneyReturn;
}
return money;
}
}
3革砸、定義一個配置類除秀,維護針對于算法的引用
/**
* 針對于算法的引用,根據(jù)具體的策略對象調(diào)用其算法方法
*/
public class StrateContext {
private Strategy strategy;
public StrateContext(Strategy strategy){
this.strategy=strategy;
}
public Double getMoney(Double money){
return strategy.getMoney(money);
}
/**
* 示例
* @param args
*/
public static void main(String[] args) {
//正常收費
StrateContext context=new StrateContext(new StrategyNormal());
Double d1=context.getMoney(100.0d);
System.out.println("正常收費:"+d1);
//滿300減100
StrateContext context1=new StrateContext(new StrategyReturn(300d,100d));
Double d2=context1.getMoney(350d);
System.out.println("滿300減100:"+d2);
//打八折
StrateContext context2=new StrateContext(new StrategyRebate(0.8d));
Double d3=context2.getMoney(100d);
System.out.println("打八折:"+d3);
}
}
后記
以上代碼僅僅實現(xiàn)了策略模式的簡單使用算利,通常業(yè)務(wù)代碼中可能還要更復雜册踩,但是萬變不離其中,通過將策略模式與工廠模式接合效拭,將可以實現(xiàn)代碼應(yīng)用的松藕合暂吉;
與工廠模式接合
獲取每一個策略都需要進行客戶端的判斷,代碼耦合太緊缎患,同時不利于后期維護慕的,僅僅這樣處理那么與采取策略模式的初衷不符;
1挤渔、創(chuàng)建一個工廠類肮街,用于實例化計算類
public class StrateContextFac {
private Strategy strategy;
public StrateContextFac(String type){
switch (type){
case "正常收費":
strategy=new StrategyNormal();
break;
case "滿300減100":
strategy=new StrategyReturn(300d,100d);
break;
case "打八折":
strategy=new StrategyRebate(0.8d);
break;
}
}
public Double getMoney(double money){
return strategy.getMoney(money);
}
}
2、調(diào)用計算
public static void contextFac(){
String type="打八折";
StrateContextFac fac=new StrateContextFac(type);
Double money=fac.getMoney(100d);
System.out.println(type+":"+money);
}
與工廠模式接合后判导,只需要關(guān)心傳入的類型與數(shù)據(jù)嫉父,而不需要去維護相關(guān)的計算類,計算類由工廠直接調(diào)用并生成眼刃;