模式定義
策略模式(Strategy Pattern):定義一系列的算法,將每一種算法封裝起來並可以相互替換使用,策略模式讓算法獨立於使用它的客戶應用而獨立變化。
概念解析:意思就是我們解決一個可能有多種解決方法(即算法)的問題的時候,我們可以先把不同的解決方法實現,然後根據具體的情況選用不同的解決方法。
模式類圖:
使用場合:
(1)、當多個類的表現行爲不同,需要在運行時動態的選擇具體要執行的行爲的時候。
(2)、需要在不同的情況下使用不同的策略,或者還可能在未來用其他方式實現的時候。
(3)、需要隱藏具體策略的實現細節,各個具體策略彼此獨立的時候。
(4)、當一個類有多種行爲,而且要在執行的時候用判斷語句選擇具體的行爲的時候,可以運用策略模式將各個條件裏面的動作,用具體的策略類來實現。
實例分析:商場打折促銷的例子。促銷方式:
1、打八折促銷商品。
2、滿1000元減200促銷商品。
3、滿200元,高於200元的部分打8折促銷商品。
在商場促銷活動中,用戶可以根據自己的實際情況選擇具體的打折方式。如有的商品打八折促銷,有的商品滿1000減200,有的商品滿200高於200的部分打八折。用戶則根據自己的具體需求選擇不同的商品,然後結賬的時候跟據不同的商品的促銷方式的不同來計算具體消費費用。
策略模式實現過程應注意以下幾點內容:
(1)、需要一個總體結構負責保存當前的具體策略,然後在具體的使用方法中調用具體策略實現相應的算法。
(2)、可以在適當的時候改變當前策略。
(3)、每一種條件分支作爲一個具體策略算法單獨實現。
代碼實現(java):
//策略接口
public interface Istrategy {
//計算實際價格的方法
public double realPrice(double consumePrice);
}
//8折促銷
public class RebateStrategy implements Istrategy {
private final double rate;
public RebateStrategy(){
this.rate=0.8;
}
public double realPrice(double consumePrice){
return consumePrice *this.rate;
}
}
//滿1000減200促銷策略
public class ReduceStrategy implements Istrategy {
public double realPrice(double consumePrice){
if(consumePrice>=10000){
return consumePrice-200;
}
else{
return consumePrice;
}
}
}
//200以上部分打8折促銷策略
public class PromotionalStrategy implements Istrategy {
public double realPrice(double consumePrice){
if(consumePrice>200){
return 200+(consumePrice-200)*0.8;
}
else{
return consumePrice;
}
}
}
//上下文環境
import java.math.BigDecimal;
public class Context {
//當前策略
private Istrategy strategy;
//設置當前策略
public void setStrategy(Istrategy strategy){
this.strategy=strategy;
}
//使用策略計算當前價格
public double cul(double consumePrice){
double realPrice=this.strategy.realPrice(consumePrice);
//-----以下內容對數字的格式進行轉換,不懂的可以看javaAPI文檔裏的java.util.math.BigDecimal
BigDecimal bd=new BigDecimal(realPrice);
bd=bd.setScale(1,BigDecimal.ROUND_DOWN);
return bd.doubleValue();
//----------------
}
}
//客戶端測試用例
import java.util.Random; //產生隨機數
public class Client {
public static void main(String args[]){
//創建上下文環境對象實例
Context context=new Context();
Random random=new Random();
for(int i=0;i<10;i++){
int x=random.nextInt(3);
double consumePrice=0;
while((consumePrice=random.nextInt(2000))==0){//產生2000以內隨機的價格
}
//調用不同的策略
switch(x){
case 0:
context.setStrategy(new RebateStrategy());
break;
case 1:
context.setStrategy(new PromotionalStrategy());
break;
case 2:
context.setStrategy(new ReduceStrategy());
break;
}
System.out.println("原價:"+consumePrice+" 優惠後價格:"+context.cul(consumePrice));
}
}
}
文章內容來源:
軟件祕笈——設計模式那點事