設計模式9:策略模式
阿新 • • 發佈:2018-12-11
策略模式
定義:策略模式定義了一系列的演算法,並將每一個演算法封裝起來,而且使他們可以相互替換,讓演算法獨立於使用它的客戶而獨立變化
本質:分離演算法,選擇實現。
看不懂這個神仙一般的定義沒關係,老規矩,先搞個反面例子來引出我們的策略模式
在暑假的第一天,有幾個選擇擺在我面前,分別是打英雄聯盟,做家務,睡覺,學習。顯然每個行為都可以看成是一種行為策略,那麼我到底會選擇什麼呢,這應該根據具體的情況來做出選擇。
if(weather.equals("出太陽")){ //打 lol }else if(weather.equals("陰天")){ //睡覺 }else if(weather.equals("下雨")){ //做家務 }else if(weather.equals("下雪")){ //學習 }
一般來說,我們會這樣用程式語言來描述,但這樣的話,存在一個問題,假如我想到一個新的選擇的話,那麼我就要在原來程式碼的基礎上增加新的else if語句,顯然這違背了我們的開發中的開放-封閉原則(具備可拓展性),所以我們要考慮下換種思路啦,我們不妨把定義一個策略介面,該介面中定義一個do方法,我們的每種行為策略都實現這個介面並實現介面中定義的方法。這樣的話當我們需要增加新的策略的時候,就只需要增加一個介面實現類就ok啦,這就是我們的策略模式。
主要角色
- 抽象策略(Strategy)角色:這是一個抽象角色,通常由一個介面或抽象類實現。此角色給出所有的具體策略類所需的介面。
- 具體策略(ConcreteStrategy)角色:包裝了相關的演算法或行為。
- 環境(Context)角色:持有一個Strategy的引用。
具體實現
首先定義個抽象策略角色
//策略介面
public interface Strategy {
void dothing();
}
再定義具體行為策略,實現策略介面
public class SunnyStrategy implements Strategy{ @Override public void dothing() { System.out.println("我要打擼啊擼,請不要阻止我"); } } public class CloudyStrategy implements Strategy{ @Override public void dothing() { System.out.println("我要睡覺zzz"); } } public class RainyStrategy implements Strategy{ @Override public void dothing() { System.out.println("我要做家務,哎"); } } public class SnowyStrategy implements Strategy{ @Override public void dothing() { System.out.println("我要學習,如果你打擾我,我就陪你玩"); } }
接著定義一個持有一個Strategy引用的環境角色,用於執行具體的策略。
public class Context {
private Strategy strategy;
public Context(Strategy stratege) {
this.strategy = stratege;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void doOneThing(){
strategy.dothing();
}
}
客戶端測試
public class Client {
public static void main(String[] args) {
Strategy sunnyday = new SunnyStrategy();
Context context = new Context(sunnyday);
context.doOneThing();
}
}
優點
- 策略模式提供了對“開閉原則”的完美支援,使用者可以在不修改原有系統的基礎上選擇演算法或行為,也可以靈活地增加新的演算法或行為。
- 策略模式提供了可以替換繼承關係的辦法。
- 使用策略模式可以避免使用多重條件轉移語句。
不足
- 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。
- 策略模式將造成產生很多策略類,
適用場景
- 如果在一個系統裡面有許多類,它們之間的區別僅在於它們的行為,那麼使用策略模式可以動態地讓一個物件在許多行為中選擇一種行為。
- 一個系統需要動態地在幾種演算法中選擇一種。
- 如果一個物件有很多的行為,如果不用恰當的模式,這些行為就只好使用多重的條件選擇語句來實現。