溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么理解Java設(shè)計(jì)模式的策略模式

發(fā)布時(shí)間:2021-11-08 09:00:43 來源:億速云 閱讀:154 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“怎么理解Java設(shè)計(jì)模式的策略模式”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么理解Java設(shè)計(jì)模式的策略模式”吧!

一、什么是策略模式

策略模式定義了一系列算法,并將每個(gè)算法封裝起來,使他們可以相互替換,且算法的變化不會影響到使用算法的客戶。需要設(shè)計(jì)一個(gè)接口,為一系列實(shí)現(xiàn)類提供統(tǒng)一的方法,多個(gè)實(shí)現(xiàn)類實(shí)現(xiàn)該接口,設(shè)計(jì)一個(gè)抽象類(可有可無,屬于輔助類),提供輔助函數(shù)。

策略模式定義和封裝了一系列的算法,它們是可以相互替換的,也就是說它們具有共性,而它們的共性就體現(xiàn)在策略接口的行為上,另外為了達(dá)到最后一句話的目的,也就是說讓算法獨(dú)立于使用它的客戶而獨(dú)立變化,我們需要讓客戶端依賴于策略接口。

一種很簡單的解釋,在我們的開發(fā)過程中,經(jīng)常會遇到大量的if...else或者switch...case語句,當(dāng)這些語句在開發(fā)中只是為了起到分流作用,這些分流和業(yè)務(wù)邏輯無關(guān),那么這個(gè)時(shí)候就可以考慮用策略模式。

二、策略模式的結(jié)構(gòu)

怎么理解Java設(shè)計(jì)模式的策略模式

這個(gè)模式涉及到三個(gè)角色:

上下文環(huán)境(Context)角色:持有一個(gè)Strategy的引用。

抽象策略(Strategy)角色:這是一個(gè)抽象角色,通常由一個(gè)接口或抽象類實(shí)現(xiàn)。此角色給出所有的具體策略類所需的接口。

具體策略(ConcreteStrategy)角色:包裝了相關(guān)的算法或行為

三、策略模式的應(yīng)用場景

舉一個(gè)例子,商場搞促銷--打8折,滿200送50,滿1000送禮物,這種促銷就是策略。

再舉一個(gè)例子,dota里面的戰(zhàn)術(shù),玩命四保一,三偽核體系,推進(jìn)體系,大招流體系等,這些戰(zhàn)術(shù)都是一種策略。

應(yīng)用場景:

1、 多個(gè)類只區(qū)別在表現(xiàn)行為不同,可以使用Strategy模式,在運(yùn)行時(shí)動態(tài)選擇具體要執(zhí)行的行為。

2、 需要在不同情況下使用不同的策略(算法),或者策略還可能在未來用其它方式來實(shí)現(xiàn)。

3、 對客戶隱藏具體策略(算法)的實(shí)現(xiàn)細(xì)節(jié),彼此完全獨(dú)立。

四、策略模式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

1、結(jié)構(gòu)清晰,把策略分離成一個(gè)個(gè)單獨(dú)的類「替換了傳統(tǒng)的 if else」2、代碼耦合度降低,安全性提高「各個(gè)策略的細(xì)節(jié)被屏蔽」

缺點(diǎn):

1、客戶端必須要知道所有的策略類,否則你不知道該使用那個(gè)策略,所以策略模式適用于提前知道所有策略的情況下2、策略類數(shù)量增多(每一個(gè)策略類復(fù)用性很小,如果需要增加算法,就只能新增類)五、策略模式和簡單工廠模式的異同

在上篇文章已經(jīng)提過了,傳送地址:深入理解設(shè)計(jì)模式(二):簡單工廠模式

六、策略模式的實(shí)現(xiàn)

Strategy類,定義所有支持的算法的公共接口

//Strategy類,定義所有支持的算法的公共接口
abstract class Strategy
{
    //算法方法
    public abstract void AlgorithmInterface();
}

oncreteStrategy,封裝了具體的算法或行為,繼承于Strategy

//算法A
    class ConcreteStrategyA : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法A的實(shí)現(xiàn)");
        }
    }
    //算法B
    class ConcreteStrategyB : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法B的實(shí)現(xiàn)");
        }
    }
    //算法C
    class ConcreteStrategyC : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法C的實(shí)現(xiàn)");
        }
    }

Context,用一個(gè)ConcreteStrategy來配置,維護(hù)一個(gè)對Strategy對象的引用

//Context,用一個(gè)ConcreteStrategy來配置,維護(hù)一個(gè)對Strategy對象的引用
    class Context
    {
        Strategy Strategy;
        public Context(Strategy Strategy)
        {
            this.Strategy = Strategy;
        }
        //上下文接口
        public void ContextInterface()
        {
            Strategy.AlgorithmInterface();
        }
    }

客戶端代碼

static void Main(string[] args)
        {
            Context Context;

            Context = new Context(new ConcreteStrategyA());
            Context.ContextInterface();

            Context = new Context(new ConcreteStrategyB());
            Context.ContextInterface();

            Context = new Context(new ConcreteStrategyC());
            Context.ContextInterface();

            Console.Read();
        }

七、策略模式和簡單工廠模式的結(jié)合

改造后的Context

class Context
    {
        Strategy Strategy=null;
        public Context(string type)
        {
            switch (type)
            {
                case "A":
                    ConcreteStrategyA A = new ConcreteStrategyA();
                    Strategy = A;
                    break;
                case "B":
                    ConcreteStrategyB B = new ConcreteStrategyB();
                    Strategy = B;
                    break;
                case "C":
                    ConcreteStrategyC C = new ConcreteStrategyC();
                    Strategy = C;
                    break;
            }
        }
        //上下文接口
        public void ContextInterface()
        {
            Strategy.AlgorithmInterface();
        }
    }

改造后的客戶端代碼

static void Main(string[] args)
        {
            Context Context = new Context("這里是相應(yīng)的算法類型字符串");
            Context.ContextInterface();

            Console.Read();
        }

對比下改造前后的區(qū)別不難看出,改造前客戶端需要認(rèn)識兩個(gè)類,Context和ConcreteStrategy。而策略模式和簡單工廠模式結(jié)合后,客戶端只需要認(rèn)識一個(gè)類Context,降低了耦合性。

八、策略枚舉的實(shí)現(xiàn)

我們可以使用枚舉在一個(gè)類中實(shí)現(xiàn)以上所有的功能及三種不同的角色,下面看看怎么通過枚舉來實(shí)現(xiàn)策略模式

public enum Calculator 
{    ADD("+") {        
        public int exec(int a, int b) {    
            return a+b;        
        }
    },        
    SUB("-") {        
        public int exec(int a, int b) {        
            return a-b;        
            }    
    };            
    public abstract int exec(int a, int b);        
    //運(yùn)算符    
    private String value = "";        
    private Calculator(String value)
    {        
        this.value = value;
    }     
    public String getValue() 
    {        
        return value;
    }
}

在枚舉類中,定義的抽象方法就像當(dāng)時(shí)之前的接口,每一個(gè)枚舉ADD SUB相當(dāng)是一個(gè)具體的實(shí)現(xiàn)類(策略角色),而整個(gè)枚舉類就是策略的分裝角色。

感謝各位的閱讀,以上就是“怎么理解Java設(shè)計(jì)模式的策略模式”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么理解Java設(shè)計(jì)模式的策略模式這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI