概念:
策略模式屬於對象的行爲模式,其用意是針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響客戶端的情況下變化。
結構:
環境(Context)角色:持有一個Strategy的引用。
抽象策略(Strategy)角色:這是一個抽象角色,通常由一個接口或抽象類實現,此角色給出所有的具體策略類所需的接口。
具體策略(ConcreteStrategy)角色:包含具體場景的算法。
代碼示例:
環境角色:
public class Context { //持有一個具體策略的對象 private Strategy strategy; /** * 構造函數,傳入一個具體策略對象 * @param strategy 具體策略對象 */ public Context(Strategy strategy){ this.strategy = strategy; } /** * 策略方法 */ public void contextInterface(){ strategy.strategyInterface(); } }
抽象策略類:
public interface Strategy { /** * 策略方法 */ public void strategyInterface(); }
具體策略類:
public class ConcreteStrategyA implements Strategy { @Override public void strategyInterface() { //相關的業務 } } //後面兩個重複這個類
使用常見:
我們以手抓餅訂單爲例,即有普通手抓餅,高級手抓餅,頂級手抓餅。
場景就是接單類,根據具體的算法來生產不同的手抓餅訂單。
接單類:
public class ReceiveOrder { private ShouzhuabingOrder shouzhuabingOrder; public ReceiveOrder(ShouzhuabingOrder shouzhuabingOrder) { this.shouzhuabingOrder = shouzhuabingOrder; } //其實這我們可以對該函數進行一些功能強化,讓其在算法選擇的基礎上進行一些功能的擴展 //具體的可以參考java中Collections類下面的sort方法。 //例如我們可以通過參數作爲輸入,相當於用戶除了做定製化的手抓餅外,還可以再次基礎上進行個性化的定製。 public String makeOrder() { return shouzhuabingOrder.makeOrder(); } }
手抓餅訂單接口:
public interface ShouzhuabingOrder { public String makeOrder(); }
普通手抓餅:
public class OriginOrder implements ShouzhuabingOrder { @Override public String makeOrder() { return "我是基礎的手抓餅,只有一張餅,一個蛋還有各種醬"; } }
高檔手抓餅:
public class MediumOrder implements ShouzhuabingOrder { @Override public String makeOrder() { return "我是一箇中級手抓餅,自帶一張餅,兩個蛋,還有自制醬料"; } }
豪華手抓餅:
public class HighOrder implements ShouzhuabingOrder { @Override public String makeOrder() { return "我是高級手抓餅,我有一張餅,兩個蛋,一個裏脊,一個薄脆還有自制醬料。"; } }
實際的接受訂單的過程:
public class Test { public static void main(String[] args) { HighOrder highOrder = new HighOrder(); ReceiveOrder receiveOrder = new ReceiveOrder(highOrder); System.out.println(receiveOrder.makeOrder()); } }
策略模式的核心:
不管算法的實現,而是對算法做一個選擇,組織,調用,從而使程序在結構上更加清晰,也更加方便維護和擴展。
策略模式的平等性:
算法的地位相同,可以相互替換,相互無依賴,策略模式中的算法關係未:相同行爲的不同實現。
策略模式運行時的唯一性:
運行時,每一個時刻只能使用一個具體的策略實現對象,雖然可以動態切換,但是在同一時刻,只能是一個。
共有行爲:
若所有算法均有具體的行爲,可以將算法接口改成抽象類,同時共有的行爲進行定義。
策略模式的優點:
1.策略模式提供了管理相關算法的算法族的方法,可以將部分共有代碼移到父類,從而避免重複。
2.使用策略模式,可以避免重複條件的判定(if-else)。
策略模式的缺點:
1.客戶端必須知道所有的策略,並自行決定使用哪種策略,以便選用合適的算法。(我還沒有想明白這點,這自行判斷還不是要依賴if else)
2.備選的策略多的話,類的數量會很多,不方便管理。