策略模式用於算法的自由切換和擴展,實現了算法定義和算法分離的使用html
要完成一項任務,能夠有多種不一樣的方式,例如人們外出旅遊時能夠選擇多種不一樣的出行方式,如自行車、坐汽車、坐高鐵或乘飛機等,每一種方式稱爲一個策略,咱們能夠根據環境或者條件的不一樣選擇不一樣的策略來完成該任務。java
在實際的軟件開發中,一項功能也有不少算法能夠實現,若是咱們直接把多種算法集中在一個類,或者說使用條件判斷語句來進行選擇,無疑會增長代碼複雜性,不利於維護。算法
爲了解決這些問題,能夠定義一些獨立的類來封裝不一樣的算法,每一類封裝一個具體的算法,將每個封裝算法的類稱之爲策略(Strategy)。爲了保證策略的一致性,通常會用一個抽象的策略類來作算法的定義,每種具體算法對應於一個具體策略類。編程
策略模式(Strategy Pattern)定義一系列算法,將每一個算法封裝起來,並讓它們能夠相互替換。策略模式讓算法獨立於使用它的客戶而變化,也稱政策模式(Policy)。策略模式是一種對象行爲模式。this
Define a famliy of algorithms, encapsulate each one,and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.設計
說到策略模式就不得不提一下狀態模式了,一個是對狀態的封裝,另外一個則是對算法的封裝,所以實現方式上二者有許多共同點,理解起來並不複雜code
點這裏瞭解狀態模式htm
策略模式是對算法的封裝,把算法的責任和算法自己分割開來,委託給不一樣對象管理。策略模式一般把一系列算法封裝到一系列的策略類裏面,做爲一個抽象策略類的子類。對象
由此能夠得出結構類圖以下:blog
環境類(Context)是須要使用算法的對象,它在解決某個問題時能夠採用多種策略,在環境類中維護一個對抽象策略類的引用實例,用於定義所採用的策略。假如咱們不使用策略模式,可能會存在以下代碼:
public class Context { ... public void algorithm(String type) { ... if(type == "strategyA") { // 算法A } else if(type == "strategyB") { // 算法B } else if(type == "strategyC") { // 算法C } ... } ... }
客戶端要調用 Context 類的 algorithm() 方法時,須要根據所傳入的參數來選擇具體算法,這將致使代碼過於龐大,不利於維護。並且最大的問題是,在環境類中定義算法,若是須要修改或增長算法,則勢必要修改源代碼,違反了開閉原則。
致使以上問題的主要緣由在於環境類職責太重,即違背了單一職責原則,策略模式正是解決這個問題的好幫手。引入一個抽象策略類(Strategy),在其中定義抽象算法,每個繼承它的具體策略類(ConcreteStrategy)使用具體算法實現某個業務辦理。環境類只針對抽象策略類編程,符合依賴倒轉原則,出現新的算法時,只須要增長一個新的實現了抽象策略類的具體策略類便可。
public abstract class AbstractStrategy { public abstract void algorithm(); }
將每一種具體算法做爲該抽象策略類的子類
public class ConcreteStrategyA extends AbstractStrategy { public void algorithm() { // 算法A } }
對於環境類,在它與抽象策略類之間創建一個關聯關係
public class Context { private AbstractStrategy strategy; public void setStrategy(AbstractStrategy strategy) { this.strategy = strategy; } public void algorithm() { strategy.algorithm(); } }
對於用戶而言,使用環境類時只需注入一個具體策略對象便可。用戶能夠靈活更換具體策略類,好比使用配置文件,增長新的具體策略類也很方便,所以策略模式至關於「即插即用的算法」。
須要注意的是,策略模式並不負責「哪個具體策略類適用於哪種狀況」這個決定,換言之,應當由客戶決定在什麼狀況下使用什麼具體策略角色,必定程度上提升了系統靈活性,但前提是客戶須要理解因此具體策略類之間的區別及最佳使用場景。
對比狀態模式,狀態模式能夠實現自主的狀態切換,並根據狀態的不一樣作出不一樣的行爲。而
策略模式的優勢:
策略模式的缺點:
因爲結構的類似性,因此很容易會把策略模式和狀態模式混餚,但它們是爲解決不一樣的問題而設計的,是徹底不一樣的兩種模式。如何區分是策略模式仍是狀態模式?其區別以下: