定義一組算法,將每一個算法都封裝起來,而且使它們之間能夠互換。策略模式使這些算法在客戶端調用它們的時候可以互不影響地變化。(Java的TreeSet集合中,構造方法可傳入具體的比較器對象以實現不一樣的排序算法。就是利用的策略模式)策略模式的用意是針對一組算法,將每個算法封裝到具備共同接口的獨立的類中, 從而使得它們能夠相互替換,使用策略模式能夠把行爲和環境分割開來。java
環境角色:持有一個策略類的引用,最終給客戶端調用的。經過環境角色指定策略。算法
模 擬 鴨 子 遊 戲 :SimUDuck。遊戲中會出現各類鴨子,一邊游泳戲水,一邊呱
呱叫。不一樣的鴨子有不一樣的行爲,因此咱們能夠把鴨子會不會飛,怎麼飛的行爲定義爲抽象策略角色,鴨子叫行爲也定義成一種策略,由於叫法不一樣。ide
把會變化的部分取出並封裝起來,以便之後能夠輕易地改動或擴充此部分,而不影響不須要變化的其餘部分。
咱們先抽象一個Duck類,鴨子有 fly() 和 quack() ,可是會隨着鴨子的不一樣而改變,因此咱們要抽出來,將他們定義爲變的部分涉及成策略,Duck 類持有對應策略的引用,經過組合的方式實現。
this
最後咱們整合鴨子的行爲,分別將鴨子的飛行與嘎嘎叫的動做 "委託"(delagate)別人處理,而不是定義在Duck類中。
咱們用兩個類似的方法performFly()和performQuack()取代鴨子類中的fly()與quack()。設計
定義 Duck 抽象類,全部的鴨子都繼承。經過組合代理的模式實現飛行與嘎嘎叫的功能,持有策略類(飛行,呱呱叫)的引用。
提供set方法指定不一樣的策略,而後經過 performFly 與 performQuack 委託對應的策略實現。代理
public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } /** * 展現鴨子 */ public abstract void display(); public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } }
定義野鴨子:會飛,呱呱叫。code
public class MallardDuck extends Duck { @Override public void display() { System.out.println("我是一隻野鴨子"); } }
定義模型鴨子:不會飛也不會叫。orm
public class ModelDuck extends Duck { @Override public void display() { System.out.println("我是一隻模型鴨子"); } }
叫聲抽象策略對象
public interface QuackBehavior { void quack(); }
飛行抽象策略blog
public interface FlyBehavior { void fly(); }
實現抽象策略,規定算法邏輯。
public class FlyNoWay implements FlyBehavior { @Override public void fly() { System.out.println("老司機帶帶我,我不會飛"); } }
public class FlyWithWings implements FlyBehavior { @Override public void fly() { System.out.println("我會飛行,一衝雲霄"); } }
public class Quack implements QuackBehavior { @Override public void quack() { System.out.println("呱呱叫"); } }
public class MuteQuack implements QuackBehavior { @Override public void quack() { System.out.println("我不會叫"); } }
public class MallardDuck extends Duck { @Override public void display() { System.out.println("我是一隻野鴨子"); } }
public class ModelDuck extends Duck { @Override public void display() { System.out.println("我是一隻模型鴨子"); } }
public class MiniDuckSimulator { public static void main(String[] args) { //定義不會叫不會飛的鴨子 FlyBehavior flyBehavior = new FlyNoWay(); QuackBehavior quackBehavior = new MuteQuack(); Duck modelDuck = new ModelDuck(); //這裏咱們能夠設置不一樣的行爲實現類就會執行不一樣的策略 modelDuck.setFlyBehavior(flyBehavior); modelDuck.setQuackBehavior(quackBehavior); modelDuck.display(); modelDuck.performFly(); modelDuck.performQuack(); System.out.println("-------------------"); // 定義會叫會飛的鴨子 FlyBehavior flyWithWings = new FlyWithWings(); QuackBehavior quack = new Quack(); Duck mallardDuck = new MallardDuck(); mallardDuck.setFlyBehavior(flyWithWings); mallardDuck.setQuackBehavior(quack); mallardDuck.display(); mallardDuck.performFly(); mallardDuck.performQuack(); } }
其實就是將將不一樣的算法抽象,經過上下文切換策略實現不一樣行爲。咱們是否是還可使用策略模式代替不少的if else 判斷執行不一樣的算邏輯?這裏留給讀者去發現使用場景。
關注公衆號 JavaStorm 獲取最新文章,不點個贊麼?