策略模式(Strategy Pattern)
屬於對象行爲型模式
的一種,其用意是 針對一組算法,將每個算法封裝到具備共同接口的獨立的類中,從而使得它們能夠相互替換。策略模式使得算法能夠在不影響到客戶端的狀況下發生變化。
<!-- more -->html
策略模式: 是對算法的包裝,是把使用算法的責任和算法自己分割開來,委派給不一樣的對象管理。策略模式一般把一個系列的算法包裝到一系列的策略類裏面,做爲一個抽象策略類的子類。用一句話來講,就是:「準備一組算法,並將每個算法封裝起來,使得它們能夠互換」。下面就以一個示意性的實現講解策略模式實例的結構。java
UML結構圖
模式結構
Strategy
的引用。採用上文的UML圖
以及分析出的模式結構,寫一個簡單的購物折扣
功能git
假設如今要上線一個販賣各種書籍的電子商務網站的折扣功能
。一個最簡單的狀況就是把全部貨品的單價乘上數量,可是實際狀況確定比這要複雜。好比,本網站可能對全部的高級會員提供每本20%的促銷折扣;對中級會員提供每本10%的促銷折扣;對初級會員沒有折扣。算法
根據描述,折扣是根據如下的幾個算法中的一個進行的:微信
結構圖以下:
1.定義抽象折扣類ide
/** * 會員優惠策略 */ interface MemberStrategy { /** * 計算圖書的價格 * * @param booksPrice 圖書的原價 * @return 計算出打折後的價格 */ double calcPrice(double booksPrice); }
2.建立三個 具體策略類 ,表明三種不一樣計算規則函數
class PrimaryMemberStrategy implements MemberStrategy { @Override public double calcPrice(double booksPrice) { System.out.println("對於初級會員的沒有折扣"); return booksPrice; } } class IntermediateMemberStrategy implements MemberStrategy { @Override public double calcPrice(double booksPrice) { System.out.println("對於中級會員的折扣爲10%"); return booksPrice * 0.9; } } class AdvancedMemberStrategy implements MemberStrategy { @Override public double calcPrice(double booksPrice) { System.out.println("對於高級會員的折扣爲20%"); return booksPrice * 0.8; } }
3.建立 環境(Context)角色 價格類,持有抽象決策的引用測試
class Price { /** * 持有一個具體的策略對象 */ private MemberStrategy strategy; /** * 構造函數,傳入一個具體的策略對象 * * @param strategy 具體的策略對象 */ public Price(MemberStrategy strategy) { this.strategy = strategy; } /** * 計算圖書的價格 * * @param booksPrice 圖書的原價 * @return 計算出打折後的價格 */ public double quote(double booksPrice) { return this.strategy.calcPrice(booksPrice); } }
4.建立客戶端,用於測試網站
public class Client { public static void main(String[] args) { Price price; //建立環境 price = new Price(new PrimaryMemberStrategy()); //計算價格 System.out.println("圖書的最終價格爲:" + price.quote(300)); //建立環境 price = new Price(new AdvancedMemberStrategy()); //計算價格 System.out.println("圖書的最終價格爲:" + price.quote(300)); } }
6.運行結果this
對於初級會員的沒有折扣 圖書的最終價格爲:300.0 對於高級會員的折扣爲20% 圖書的最終價格爲:240.0
從上面的示例能夠看出,策略模式僅僅封裝算法,提供新的算法插入到已有系統中,以及老算法從系統中「退休」的方法,策略模式並不決定在什麼時候使用何種算法。在什麼狀況下使用什麼算法是由客戶端決定的。
重心
策略模式的重心不是如何實現算法,而是如何組織、調用這些算法,從而讓程序結構更靈活,具備更好的維護性和擴展性。
算法平等性
策略模式一個很大的特色就是各個策略算法的平等性。對於一系列具體的策略算法,你們的地位是徹底同樣的,正由於這個平等性,才能實現算法之間能夠相互替換。全部的策略算法在實現上也是相互獨立的,相互之間是沒有依賴的。
因此能夠這樣描述這一系列策略算法:策略算法是相同行爲的不一樣實現。
策略的惟一性
運行期間,策略模式在每個時刻只能使用一個具體的策略實現對象,雖然能夠動態地在不一樣的策略實現中切換,可是同時只能使用一個。
公有的行爲
常常見到的是,全部的具體策略類都有一些公有的行爲。這時候,就應當把這些公有的行爲放到共同的抽象策略角色Strategy
類裏面。固然這時候抽象策略角色必需要用Java抽象類實現,而不能使用接口。
這其實也是典型的將代碼向繼承等級結構的上方集中的標準作法。
優勢
缺點
參考文獻:http://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html
全文代碼:https://gitee.com/battcn/design-pattern/tree/master/Chapter18/battcn-strategy
微信公衆號:battcn
(歡迎調戲)