您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么理解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í)候就可以考慮用策略模式。
這個(gè)模式涉及到三個(gè)角色:
上下文環(huán)境(Context
)角色:持有一個(gè)Strategy的引用。
抽象策略(Strategy
)角色:這是一個(gè)抽象角色,通常由一個(gè)接口或抽象類實(shí)現(xiàn)。此角色給出所有的具體策略類所需的接口。
具體策略(ConcreteStrategy
)角色:包裝了相關(guān)的算法或行為
舉一個(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):
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ì)模式(二):簡單工廠模式
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(); }
改造后的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,降低了耦合性。
我們可以使用枚舉在一個(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)注!
免責(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)容。