設(shè)計(jì)模式解密(3)- 策略模式
1、簡(jiǎn)介
定義:定義一組算法,將每個(gè)算法都封裝起來(lái),并且使他們之間可以互換。
策略模式的決定權(quán)在用戶,系統(tǒng)本身提供不同算法的實(shí)現(xiàn),新增或者刪除算法,對(duì)各種算法做封裝。因此,策略模式多用在算法決策系統(tǒng)中,外部用戶只需要決定用哪個(gè)算法即可。
類型:行為類模式
2、實(shí)例引入
背景:模擬商城的促銷活動(dòng),旨在了解模式
先定義一個(gè)活動(dòng)接口:
1 2 3 4 5 6 7 8 | package com.designpattern.strategy; /** * 類說(shuō)明 :促銷活動(dòng)抽象接口 */ public interface AbstractSaleActivity { public void saleEvent(); } |
定義3個(gè)具體的活動(dòng):
1 2 3 4 5 6 7 8 9 10 11 12 | package com.designpattern.strategy; /** * 類說(shuō)明 :定義具體的促銷活動(dòng) - 518活動(dòng) */ public class SaleActivity618 implements AbstractSaleActivity { @Override public void saleEvent() { //TODO 業(yè)務(wù)邏輯 System.out.println( "618促銷活動(dòng)!" ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 | package com.designpattern.strategy; /** * 類說(shuō)明 :定義具體的促銷活動(dòng) - 1111活動(dòng) */ public class SaleActivity1111 implements AbstractSaleActivity { @Override public void saleEvent() { // TODO 業(yè)務(wù)邏輯 System.out.println( "雙十一促銷活動(dòng)!" ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 | package com.designpattern.strategy; /** * 類說(shuō)明 :定義具體的促銷活動(dòng) - 1212活動(dòng) */ public class SaleActivity1212 implements AbstractSaleActivity{ @Override public void saleEvent() { // TODO 業(yè)務(wù)邏輯 System.out.println( "雙十二促銷活動(dòng)!" ); } } |
定義活動(dòng)入口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | package com.designpattern.strategy; /** * 類說(shuō)明 :活動(dòng)入口 */ public class ActivityEntry { public void activityEntry(String str){ AbstractSaleActivity saleActivity = null ; switch (str){ case "618" : saleActivity = new SaleActivity618(); saleActivity.saleEvent(); break ; case "1111" : saleActivity = new SaleActivity1111(); saleActivity.saleEvent(); break ; case "1212" : saleActivity = new SaleActivity1212(); saleActivity.saleEvent(); break ; default : System.out.println( "無(wú)具體活動(dòng)!" ); break ; } } } |
測(cè)試:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package com.designpattern.strategy; /** * 類說(shuō)明 :測(cè)試 */ public class Test { public static void main(String[] args) { //618活動(dòng) ActivityEntry activity = new ActivityEntry(); activity.activityEntry( "618" ); //1111活動(dòng) ActivityEntry activity1 = new ActivityEntry(); activity1.activityEntry( "1111" ); //1212活動(dòng) ActivityEntry activity2 = new ActivityEntry(); activity2.activityEntry( "1212" ); } } |
結(jié)果:
1 2 3 | 618促銷活動(dòng)! 雙十一促銷活動(dòng)! 雙十二促銷活動(dòng)! |
是不是對(duì)策略模式有一定了解了?
3、解決的問(wèn)題
客戶端(調(diào)用者)可以根據(jù)條件來(lái)選擇不同的策略來(lái)解決不同的問(wèn)題。
4、優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
策略類之間可以自由切換,由于策略類實(shí)現(xiàn)自同一個(gè)抽象,所以他們之間可以自由切換。
易于擴(kuò)展,增加一個(gè)新的策略對(duì)策略模式來(lái)說(shuō)非常容易,基本上可以在不改變?cè)写a的基礎(chǔ)上進(jìn)行擴(kuò)展。
缺點(diǎn):
維護(hù)各個(gè)策略類會(huì)給開(kāi)發(fā)帶來(lái)額外開(kāi)銷,隨著策略類的數(shù)量逐漸增多,就令人頭疼了。
必須對(duì)客戶端(調(diào)用者)暴露所有的策略類,因?yàn)槭褂媚姆N策略是由客戶端來(lái)決定的,因此,客戶端應(yīng)該知道有什么策略,并且了解各種策略之間的區(qū)別,否則,后果很嚴(yán)重。例如,有一個(gè)排序算法的策略模式,提供了快速排序、冒泡排序、選擇排序這三種算法,客戶端在使用這些算法之前,是不是先要明白這三種算法的適用情況?再比如,客戶端要使用一個(gè)容器,有鏈表實(shí)現(xiàn)的,也有數(shù)組實(shí)現(xiàn)的,客戶端是不是也要明白鏈表和數(shù)組有什么區(qū)別?就這一點(diǎn)來(lái)說(shuō)是有悖于迪米特法則的。
5、應(yīng)用場(chǎng)景
幾個(gè)類的主要邏輯相同,只在部分邏輯的算法和行為上稍有區(qū)別的情況。
有幾種相似的行為,或者說(shuō)算法,客戶端需要?jiǎng)討B(tài)地決定使用哪一種,那么可以使用策略模式,將這些算法封裝起來(lái)供客戶端調(diào)用。
6、總結(jié)
策略模式是一種簡(jiǎn)單常用的模式,我們?cè)谶M(jìn)行開(kāi)發(fā)的時(shí)候,會(huì)經(jīng)常有意無(wú)意地使用它,一般來(lái)說(shuō),策略模式不會(huì)單獨(dú)使用,跟模版方法模式、工廠模式等混合使用的情況比較多。
PS:源碼地址 https://github.com/JsonShare/DesignPattern/tree/master
如果您覺(jué)得閱讀本文對(duì)您有幫助,請(qǐng)點(diǎn)一下“推薦”按鈕,您的“推薦”將是我最大的寫(xiě)作動(dòng)力!
如果標(biāo)題被標(biāo)記為轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明原作者地址,詳見(jiàn)引用
版權(quán)聲明,轉(zhuǎn)載請(qǐng)注明出處:http://www.cnblogs.com/JsonShare
http://www.cnblogs.com/JsonShare/p/7109983.html