設(shè)計(jì)模式解密(3)- 策略模式

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計(jì)算培訓(xùn),高端軟件開(kāi)發(fā)培訓(xùn),項(xiàng)目經(jīng)理培訓(xùn)

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