策略模式標準定義:定義一系列的算法,把它們一個個封裝起來,而且使它們可相互替換。本模式使得算法可獨立於使用它的客戶而變化。算法
策略(Strategy)模式屬於對象的行爲模式,經過分析Strategy模式能夠發現:策略模式針對一組算法,將每個算法封裝到具備共同接口的獨立的類中,從而使得它們能夠相互替換。策略模式使得算法能夠在不影響到客戶端的狀況下發生變化。策略模式把行爲和環境分開。環境類負責維持和查詢行爲類,各類算法在具體的策略類中提供。因爲算法和環境獨立開來,算法的增減,修改都不會影響到環境和客戶端。編程
在軟件設計中,常常會遇到由於一開始考慮不夠長遠而致使後面遇到很大的麻煩。開發者只是想盡快地解決問題而沒考慮到後期的維護或者根本無法預料到未來會有什麼樣的變化乾脆置之不理。針對這個問題,Strategy模式提供了一個解決問題的方案:面向接口編程而不是實現,發現其中會改變的部分做爲擴展點,而後把它封裝起來。ide
經典案例:根據會員打折問題,代碼以下:測試
/**this
*.net
* @describe:計算價格的策略接口設計
* @author 2017年11月30日對象
*繼承
*/接口
public interface Strategy {
public double calculatePrice(double price);
}
/**
*
* @describe:普通會員策略
* @author 2017年11月30日
*
*/
public class CommonMemberStrategy implements Strategy{
public double calculatePrice(double price) {
System.out.println("您是普通會員,只能打95折。");
return price*0.95;
}
}
/**
*
* @describe:黃金會員策略
* @author 2017年11月30日
*
*/
public class GoldMemberStrategy implements Strategy{
@Override
public double calculatePrice(double price) {
System.out.println("您是黃金會員,能打9折。");
return price*0.9;
}
}
/**
*
* @describe:鑽石會員策略
* @author 2017年11月30日
*
*/
public class DiamondMemberStrategy implements Strategy{
@Override
public double calculatePrice(double price) {
System.out.println("您是鑽石會員,能打8折哦。");
return price*0.8;
}
}
/**
*
* @describe:價格類
* @author 2017年11月30日
*
*/
public class Price {
private Strategy strategy;
public Price(Strategy strategy){
this.strategy=strategy;
}
//根據策略計算價格
public double finalPrice(double price){
return strategy.calculatePrice(price);
}
}
/**
*
* @describe:測試類
* @author 2017年11月30日
*
*/
public class Test {
public static void main(String[] args) {
double pric=100;
Strategy strategy=new CommonMemberStrategy();
Price price=new Price(strategy);
System.out.println(price.finalPrice(pric));
strategy=new GoldMemberStrategy();
price=new Price(strategy);
System.out.println(price.finalPrice(pric));
strategy=new DiamondMemberStrategy();
price=new Price(strategy);
System.out.println(price.finalPrice(pric));
}
}
運行結果:
您是普通會員,只能打95折。
95.0
您是黃金會員,能打9折。
90.0
您是鑽石會員,能打8折哦。
80.0
認識策略模式
策略模式的重心
策略模式的重心不是如何實現算法,而是如何組織、調用這些算法,從而讓程序結構更靈活,具備更好的維護性和擴展性。
算法的平等性
策略模式一個很大的特色就是各個策略算法的平等性。對於一系列具體的策略算法,你們的地位是徹底同樣的,正由於這個平等性,才能實現算法之間能夠相互替換。全部的策略算法在實現上也是相互獨立的,相互之間是沒有依賴的。
因此能夠這樣描述這一系列策略算法:策略算法是相同行爲的不一樣實現。
運行時策略的惟一性
運行期間,策略模式在每個時刻只能使用一個具體的策略實現對象,雖然能夠動態地在不一樣的策略實現中切換,可是同時只能使用一個。
公有的行爲
常常見到的是,全部的具體策略類都有一些公有的行爲。這時候,就應當把這些公有的行爲放到共同的抽象策略角色Strategy類裏面。固然這時候抽象策略角色必需要用Java抽象類實現,而不能使用接口。
策略模式的優勢
(1)策略模式提供了管理相關的算法族的辦法。策略類的等級結構定義了一個算法或行爲族。恰當使用繼承能夠把公共的代碼移到父類裏面,從而避免代碼重複。
(2)使用策略模式能夠避免使用多重條件(if-else)語句。多重條件語句不易維護,它把採起哪種算法或採起哪種行爲的邏輯與算法或行爲的邏輯混合在一塊兒,通通列在一個多重條件語句裏面,比使用繼承的辦法還要原始和落後。
策略模式的缺點
(1)客戶端必須知道全部的策略類,並自行決定使用哪個策略類。這就意味着客戶端必須理解這些算法的區別,以便適時選擇恰當的算法類。換言之,策略模式只適用於客戶端知道算法或行爲的狀況。
(2)因爲策略模式把每一個具體的策略實現都單獨封裝成爲類,若是備選的策略不少的話,那麼對象的數目就會很可觀。