策略模式屬于對象的行為模式。其用意是針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響到客戶端的情況下發(fā)生變化。
老王最近接到一個工作,上級領(lǐng)導安排他對大家進行一次關(guān)于設計模式的科普培訓。小蔡被安排座位老王的助手,一起準備這次培訓。
小蔡以前從來不知道什么叫做設計模式,一聽就感覺高深莫測,有一種不明覺厲的感覺。
于是小蔡問老王:“老王啊,什么叫做設計模式呢?”
老王回答:“設計模式,簡單來將,就是一套經(jīng)驗,一套總結(jié),沒什么玄乎的。不過學了設計模式之后,對我們未來的工作是大有好處的?!?/p>
小蔡接著問:“那你先給我講講唄,我作為助手,什么都不知道,這讓別人指導了,可就丟臉了?!?/p>
老王說:“好啊, 那我們今天先來說說策略模式吧。策略模式屬于對象的行為模式。其用意是針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響到客戶端的情況下發(fā)生變化?!?/p>
小蔡兩眼直發(fā)愣:“老王,你說的都是些啥,火星語嗎?完全聽不懂?!?/p>
老王說:“先別著急,剛只是跟你說了一下策略模式的定義,接下來給你舉一個例子,你就明白了。對了,你知道咱們公司人稱“冰雪美人”的程妹妹最喜歡吃什么不?”
小蔡單手一輝說:“她啊。最喜歡吃火鍋,不過她的口味可是很挑剔的,咋的?你對她有意思?”
老王沒有瞧小蔡,接著說:“好的,她喜歡吃火鍋,而且口味挑剔。那好,我用策略模式來滿足她喜歡吃火鍋的要求?!?/p>
小蔡一下興奮起來:“吃個火鍋都能和設計模式聯(lián)系起來?”
老王接著說:“假設公司里的張董想要追求程妹妹,想請程妹妹到家里吃火鍋。張董得先請一個廚師,對吧?那么我們就來定義一個接口,告訴張董什么叫做廚師?!?/p>
//這是一個廚師public interface Cook { //是廚師就得會做火鍋 HotPot cook(); }
小蔡打趣道:“張董還不知道廚師是干嘛的?需要我們告訴他嗎?”
老王白了小蔡一眼,接著說:“張董現(xiàn)在知道什么是廚師了。于是張總按照這個標準到廚師學校去找廚師,到了廚師學校,他發(fā)現(xiàn)了三個廚師,一個四川廚師,一個北京廚師,一個潮汕廚師?!?/p>
//北京廚師public class CookOfBeijing implements Cook { //北京廚師做的就是北京火鍋 @Override public HotPot cook() { HotPotOfBeijing hotPot = new HotPotOfBeijing(); return hotPot; } }//潮汕廚師public class CookOfChaoshan implements Cook { //潮汕廚師做的就是潮汕火鍋 @Override public HotPot cook() { HotPotOfChaoshan hotPot = new HotPotOfChaoshan(); return hotPot; } }//四川廚師public class CookOfSichuan implements Cook { //四川廚師做的就是四川火鍋 @Override public HotPot cook() { HotPotOfSichuan hotPot = new HotPotOfSichuan(); return hotPot; } }
小蔡留著口水問:“原來火鍋也分地區(qū)的啊?那這些火鍋有什么區(qū)別呢?”
老王習慣性的呷了一口茶后說:“別著急,你不知道他們的區(qū)別,咱們張董也不知道呢,我們繼續(xù)來看看這些火鍋有些什么區(qū)別和特點。”
//北京火鍋public class HotPotOfBeijing extends HotPot { //北京老火鍋,可是銅火鍋,以前皇帝都用這個。 public HotPotOfBeijing() { super("銅火鍋啊~銅火鍋~"); } }//潮汕火鍋public class HotPotOfChaoshan extends HotPot{ //潮汕的牛肉火鍋,味道鮮香棒 public HotPotOfChaoshan() { super("吃牛肉啊~吃牛肉~"); } }//四川火鍋public class HotPotOfSichuan extends HotPot{ //四川火鍋的特點是:麻辣燙 public HotPotOfSichuan() { super("麻辣燙啊~麻辣燙~"); } }
小蔡:“現(xiàn)在火鍋的特點知道了,廚師也有了,然后開始做火鍋了?”
老王:“廚師有了?;疱佒懒?。但是還需要一個東西,才能做火鍋,那就是廚房,對吧?我們來看看廚房是什么樣的。”
//廚房,做火鍋的地方public class Kitchen { //掌勺的主廚 private Cook cook; //廚師進廚房了 public Kitchen(Cook cook) { super(); this.cook = cook; } //開工,做一個火鍋出來 public HotPot cook(){ return cook.cook(); } }
小蔡打斷了老王:“老王,現(xiàn)在廚師,廚房,火鍋全有了,聽得我肚子都餓了,但是我們要講的策略模式在哪里呢?”
老王又呷了一口茶,說:“別著急嘛,準備工作做好了,接下來我們就開始吃火鍋,哦,不對,應該是讓張董去追程妹妹,追程妹妹總得講點策略吧。這就是我們要講的策略模式了?!?/p>
//開始追求程妹妹public class Chasing { //追求活動 public static void main(String[] args) { //叫來北京廚師 CookOfBeijing cookOfBeijing = new CookOfBeijing(); //讓北京廚師進廚房 Kitchen kitchen = new Kitchen(cookOfBeijing); //做出北京火鍋 HotPot hotPot = kitchen.cook(); //問問程妹妹是否喜歡北京火鍋 //結(jié)果發(fā)現(xiàn)程妹妹不喜歡北京火鍋 //叫來潮汕廚師 CookOfChaoshan cookOfChaoshan = new CookOfChaoshan(); //讓潮汕廚師進廚房 kitchen = new Kitchen(cookOfChaoshan); //做出潮汕火鍋 hotPot = kitchen.cook(); //問問程妹妹是否喜歡潮汕火鍋 //結(jié)果發(fā)現(xiàn)程妹妹不喜歡潮汕火鍋 //叫來四川廚師 CookOfSichuan cookOfSichuan = new CookOfSichuan(); //讓潮汕廚師進廚房 kitchen = new Kitchen(cookOfSichuan); //做出潮汕火鍋 hotPot = kitchen.cook(); //問問程妹妹是否喜歡四川火鍋 //發(fā)現(xiàn)程妹妹很喜歡四川火鍋 //于是張董和程妹妹開始開心的吃火鍋 //一直吃到23:26 //然后出去散步,看午夜場電影……………… } }
老王又呷了一口茶,說道:“小蔡,你看,這就是策略模式。首先定義一個接口,這就相當于是制定了一條策略,然后依照這個策略編寫不同的實現(xiàn)類,就相當于一條策略有不同的實施辦法。這個模式的優(yōu)勢在于可以動態(tài)的改變對象的行為。再聚個例子,比如京東針對它的會員,有不同的會員算法,比如金牌會員算法,銀牌會員算法,銅牌會員算法。這就是針對會員算法這一個固定的策略,有了不同的實現(xiàn)。”
小蔡投來羨慕的目光:“老王,你真是太有才了。這樣的例子,我能懂,不過我還有點迷糊,不知道策略模式該如何去做,你能幫我歸納一下嗎?”
老王:“可以啊。策略模式主要有3個角色,1.環(huán)境類(Context):就是剛才說道的廚房。2. 抽象策略類(Strategy):這個是廚師接口。具體策略類(ConcreteStrategy):這就是那三個廚師。我們用一個圖來表示,能夠更加清晰易懂?!?/p>
小蔡:“老王,我發(fā)現(xiàn)另一個事兒?!?/p>
老王:“什么事兒?”
小蔡:“我肚子餓了。今天你得請我吃火鍋?!?/p>
老王:“好好好,走嘛,今天晚上我們吃火鍋。吃完之后,我們也去看一場電影哇?”
小蔡:“那得看火鍋好不好吃了。哈哈”