摘要:在這個(gè)算法類中封裝了大量查找算法,該類代碼將較復(fù)雜,維護(hù)較為困難。換言之,策略模式只適用于客戶端知道算法或行為的情況。策略模式概覽圖參考菜鳥教程策略模式十種常用的設(shè)計(jì)模式大部分自己總結(jié),部分摘抄與模式之策略模式
策略模式
? 我們都知道商場(chǎng)打折的時(shí)候,會(huì)根據(jù)會(huì)員的等級(jí)情況進(jìn)行不同的折扣優(yōu)惠,如果是VIP會(huì)員,那么可能就是5折優(yōu)惠,如果是一般會(huì)員就是8折優(yōu)惠,如果是普通顧客就是9折優(yōu)惠,那么在結(jié)賬的時(shí)候如何根據(jù)會(huì)員的等級(jí)進(jìn)行不同的計(jì)算價(jià)格的方式呢?那么這個(gè)時(shí)候策略模式就派上用場(chǎng)了
定義定義一組算法,將每個(gè)算法都封裝起來,并且使他們之間可以互換。
動(dòng)機(jī)? 在軟件系統(tǒng)中,有許多算法可以實(shí)現(xiàn)某一功能,如查找、排序等,一種常用的方法是硬編碼(Hard Coding)在一個(gè)類中,如需要提供多種查找算法,可以將這些算法寫到一個(gè)類中,在該類中提供多個(gè)方法,每一個(gè)方法對(duì)應(yīng)一個(gè)具體的查找算法;
? 當(dāng)然也可以將這些查找算法封裝在一個(gè)統(tǒng)一的方法中,通過if…else…等條件判斷語句來進(jìn)行選擇。
? 這兩種實(shí)現(xiàn)方法我們都可以稱之為硬編碼,如果需要增加一種新的查找算法,需要修改封裝算法類的源代碼;更換查找算法,也需要修改客戶端調(diào)用代碼。在這個(gè)算法類中封裝了大量查找算法,該類代碼將較復(fù)雜,維護(hù)較為困難。
結(jié)構(gòu) 組件Context:持有一個(gè)Strategy的引用。
抽象策略(Strategy)角色:這是一個(gè)抽象角色,通常由一個(gè)接口或抽象類實(shí)現(xiàn)。此角色給出所有的具體策略類所需的接口。
具體策略(ConcreteStrategy)角色:包裝了相關(guān)的算法或行為。
實(shí)現(xiàn)strategy類
package Strategy; public interface Strategy { public void method1(); public void method2(); }
具體策略
package Strategy; public class ConcreteStrategy1 implements Strategy { @Override public void method1() { System.out.println("ConcreteStrategy1===算法1-version1"); } @Override public void method2() { System.out.println("ConcreteStrategy1===算法2-version1"); } }
package Strategy; public class ConcreteStrategy2 implements Strategy { @Override public void method1() { System.out.println("ConcreteStrategy2===算法1-version2"); } @Override public void method2() { System.out.println("ConcreteStrategy2====算法2-version2"); } }
context
package Strategy; public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void method(){ System.out.println("選擇算法:" ); strategy.method1(); strategy.method2(); } }
client
package Strategy; public class Client { public static void main(String[] args){ Strategy concreteStrategy1 = new ConcreteStrategy1(); Context context = new Context(concreteStrategy1); context.method(); Strategy concreteStrategy2 = new ConcreteStrategy2(); Context context1 = new Context(concreteStrategy2); context1.method(); } } //選擇算法: // ConcreteStrategy1===算法1-version1 // ConcreteStrategy1===算法2-version1 //選擇算法: // ConcreteStrategy2===算法1-version2 // ConcreteStrategy2====算法2-version2應(yīng)用案例
如果在一個(gè)系統(tǒng)里面有許多類,它們之間的區(qū)別僅在于它們的行為,那么使用策略模式可以動(dòng)態(tài)地讓一個(gè)對(duì)象在許多行為中選擇一種行為
一個(gè)系統(tǒng)需要?jiǎng)討B(tài)地在幾種算法中選擇一種
如果一個(gè)對(duì)象有很多的行為,如果不用恰當(dāng)?shù)哪J?,這些行為就只好使用多重的條件選擇語句來實(shí)現(xiàn)。
實(shí)際應(yīng)用案例:旅行的出游方式,選擇騎自行車、坐汽車,每一種旅行方式都是一個(gè)策略
strategy
package Strategy; public interface Strategy { public void travel(); }
ConcreteStrategy1
package Strategy; public class ConcreteStrategy1 implements Strategy { @Override public void travel() { System.out.println("坐飛機(jī)"); } }
ConcreteStrategy2
package Strategy; public class ConcreteStrategy2 implements Strategy { @Override public void travel() { System.out.println("坐火車"); } }
context
package Strategy; public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void method(){ System.out.println("選擇出行方式:" ); strategy.travel(); } }
client
package Strategy; public class Client { public static void main(String[] args){ Strategy concreteStrategy1 = new ConcreteStrategy1(); Context context = new Context(concreteStrategy1); context.method(); Strategy concreteStrategy2 = new ConcreteStrategy2(); Context context1 = new Context(concreteStrategy2); context1.method(); } } //選擇出行方式: // 坐飛機(jī) //選擇出行方式: // 坐火車優(yōu)點(diǎn)
繼承方面看(strategy-concreteStrategy)
可以靈活地增加新的算法或行為,只需要重新定義一個(gè)concretestrategy并實(shí)現(xiàn)strategy接口就行了
提供了管理相關(guān)的算法族的辦法,使得所有的相似的算法都繼承一個(gè)接口進(jìn)行管理
避免使用多重條件(if-else)語句。多重條件語句不易維護(hù),它把采取哪一種算法或采取哪一種行為的邏輯與算法或行為的邏輯混合在一起,統(tǒng)統(tǒng)列在一個(gè)多重條件語句里面,比使用繼承的辦法還要原始和落后
保證了各個(gè)策略算法的平等性。對(duì)于一系列具體的策略算法,大家的地位是完全一樣的,正因?yàn)檫@個(gè)平等性,才能實(shí)現(xiàn)算法之間可以相互替換。所有的策略算法在實(shí)現(xiàn)上也是相互獨(dú)立的,相互之間是沒有依賴的。
從用戶的角度來看
不修改原有系統(tǒng)的基礎(chǔ)上選擇算法或行為,將選擇算法的權(quán)力交給用戶,用戶想要哪種算法就實(shí)例化哪種
缺點(diǎn)
繼承方面看
如果一個(gè)系統(tǒng)的策略多于四個(gè),就需要考慮使用混合模式,解決策略類膨脹的問題。
用戶角度看
客戶端必須知道所有的策略類,并自行決定使用哪一個(gè)策略類。這就意味著客戶端必須理解這些算法的區(qū)別,以便適時(shí)選擇恰當(dāng)?shù)乃惴?。換言之,策略模式只適用于客戶端知道算法或行為的情況。
策略模式概覽圖 參考菜鳥教程
5. 策略模式
十種常用的設(shè)計(jì)模式(大部分自己總結(jié),部分摘抄)
《JAVA與模式》之策略模式
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74937.html
摘要:可以使用其他模式來修正這個(gè)缺陷,如工廠方法模式代理模式或享元模式。我們的策略模式只是實(shí)現(xiàn)了策略的管理,但是沒有嚴(yán)格地定義適當(dāng)?shù)膱?chǎng)景使用適當(dāng)?shù)牟呗裕趯?shí)際項(xiàng)目中,一般通過工廠方法模式來實(shí)現(xiàn)策略類的聲明。源碼地址參考文獻(xiàn)設(shè)計(jì)模式之禪 定義 Define a family of algorithms,encapsulate each one,and make them interchange...
摘要:一定義定義維基百科策略模式作爲(wèi)一種軟件設(shè)計(jì)模式,指對(duì)象有某個(gè)行爲(wèi),但是在不同的場(chǎng)景中,該行爲(wèi)有不同的實(shí)現(xiàn)算法。二策略模式圖我們看看策略模式是有怎樣設(shè)計(jì)結(jié)構(gòu)的。如中創(chuàng)建線程池,線程池任務(wù)滿時(shí),對(duì)提交的任務(wù)做處理就使用了策略模式。以前完整的看過《大話設(shè)計(jì)模式》,雖然完整看過,也做過筆記,但現(xiàn)在依然很多已經(jīng)很模糊。這段時(shí)間趁著離職,有時(shí)間,打算重新過一遍,該篇將介紹策略模式。一、定義定義(維基百科...
摘要:一定義定義維基百科策略模式作爲(wèi)一種軟件設(shè)計(jì)模式,指對(duì)象有某個(gè)行爲(wèi),但是在不同的場(chǎng)景中,該行爲(wèi)有不同的實(shí)現(xiàn)算法。二策略模式圖我們看看策略模式是有怎樣設(shè)計(jì)結(jié)構(gòu)的。如中創(chuàng)建線程池,線程池任務(wù)滿時(shí),對(duì)提交的任務(wù)做處理就使用了策略模式。以前完整的看過《大話設(shè)計(jì)模式》,雖然完整看過,也做過筆記,但現(xiàn)在依然很多已經(jīng)很模糊。這段時(shí)間趁著離職,有時(shí)間,打算重新過一遍,該篇將介紹策略模式。一、定義定義(維基百科...
摘要:一定義定義維基百科策略模式作爲(wèi)一種軟件設(shè)計(jì)模式,指對(duì)象有某個(gè)行爲(wèi),但是在不同的場(chǎng)景中,該行爲(wèi)有不同的實(shí)現(xiàn)算法。二策略模式圖我們看看策略模式是有怎樣設(shè)計(jì)結(jié)構(gòu)的。如中創(chuàng)建線程池,線程池任務(wù)滿時(shí),對(duì)提交的任務(wù)做處理就使用了策略模式。以前完整的看過《大話設(shè)計(jì)模式》,雖然完整看過,也做過筆記,但現(xiàn)在依然很多已經(jīng)很模糊。這段時(shí)間趁著離職,有時(shí)間,打算重新過一遍,該篇將介紹策略模式。一、定義定義(維基百科...
摘要:孫臏心里一萬個(gè)草泥馬在奔騰,差點(diǎn)沒噎死自己滾一邊去,我們這盤跟他賽馬開始,策略模式上場(chǎng)。在設(shè)計(jì)模式之禪中的提出通過策略枚舉和反射機(jī)制對(duì)策略模式進(jìn)行改良,膜拜了但是要添加或淘汰策略,還是得去對(duì)枚舉進(jìn)行修改,也不符合開閉原則。 今天給大家說說田忌賽馬的故事。如有雷同,純屬巧合!話說在戰(zhàn)國時(shí)期,群雄割據(jù),硝煙四起,茶余飯后還是少不了娛樂活動(dòng)的,其中賽馬是最火爆的。一天,孫臏看到田忌像個(gè)死雞似...
閱讀 25648·2021-09-29 09:41
閱讀 4812·2021-09-10 11:20
閱讀 1931·2021-09-09 09:32
閱讀 1897·2019-08-30 15:44
閱讀 3205·2019-08-29 17:13
閱讀 2816·2019-08-29 14:14
閱讀 2071·2019-08-29 14:11
閱讀 3234·2019-08-29 12:36