Java行為型設(shè)計模式之策略模式詳解
編程是一門藝術(shù),大批量的改動顯然是非常丑陋的做法,用心的琢磨寫的代碼讓它變的更美觀。
在現(xiàn)實生活中常常遇到實現(xiàn)某種目標(biāo)存在多種策略可供選擇的情況,例如超市促銷可以釆用打折、送商品、送積分等方法。
在軟件開發(fā)中也常常遇到類似的情況,當(dāng)實現(xiàn)某一個功能存在多種算法或者策略,我們可以根據(jù)環(huán)境或者條件的不同選擇不同的算法或者策略來完成該功能,如數(shù)據(jù)排序策略有快速排序、歸并排序、選擇排序、二叉樹排序等。
如果使用多重條件轉(zhuǎn)移語句實現(xiàn)(即硬編碼),不但使條件語句變得很復(fù)雜,而且增加、刪除或更換算法要修改原代碼,不易維護,違背開閉原則。如果采用策略模式就能很好解決該問題。
1.策略設(shè)計模式定義
策略(Strategy)模式:該模式定義了一系列算法,并將每個算法封裝起來,使它們可以相互替換,且算法的變化不會影響使用算法的客戶。策略模式屬于對象行為模式,它通過對算法進行封裝,把使用算法的責(zé)任和算法的實現(xiàn)分割開來,并委派給不同的對象對這些算法進行管理。
2.策略設(shè)計模式的有點與不足
策略模式的主要優(yōu)點:
- 多重條件語句不易維護,而使用策略模式可以避免使用多重條件語句,如 if…else 語句、switch…case 語句。
- 策略模式提供了一系列的可供重用的算法族,恰當(dāng)使用繼承可以把算法族的公共代碼轉(zhuǎn)移到父類里面,從而避免重復(fù)的代碼。
- 策略模式可以提供相同行為的不同實現(xiàn),客戶可以根據(jù)不同時間或空間要求選擇不同的。
- 策略模式提供了對開閉原則的完美支持,可以在不修改原代碼的情況下,靈活增加新算法。
- 策略模式把算法的使用放到環(huán)境類中,而算法的實現(xiàn)移到具體策略類中,實現(xiàn)了二者的分離。
策略設(shè)計模式的不足:
- 客戶端必須理解所有策略算法的區(qū)別,以便適時選擇恰當(dāng)?shù)乃惴悺?/li>
- 策略模式造成很多的策略類,增加維護難度。
3.策略設(shè)計模式的實現(xiàn)思路
策略模式是準備一組算法,并將這組算法封裝到一系列的策略類里面,作為一個抽象策略類的子類。策略模式的重心不是如何實現(xiàn)算法,而是如何組織這些算法,從而讓程序結(jié)構(gòu)更加靈活,具有更好的維護性和擴展性。
策略設(shè)計模式涉及的角色:
- 抽象策略(Strategy)類:定義了一個公共接口,各種不同的算法以不同的方式實現(xiàn)這個接口,環(huán)境角色使用這個接口調(diào)用不同的算法,一般使用接口或抽象類實現(xiàn)。
- 具體策略(Concrete Strategy)類:實現(xiàn)了抽象策略定義的接口,提供具體的算法實現(xiàn)。
- 環(huán)境(Context)類:持有一個策略類的引用,最終給客戶端調(diào)用。
4.代碼示例
/** * 折扣 */ public interface Discount { /** * 計算價格 * @param money * @return */ public int calculate(int money); } /** * 滿減策略 * 需要滿200 */ public class FullDiscount implements Discount{ @Override public int calculate(int money) { if (money>200){ System.out.println("符合滿減策略,進行滿減"); return money - 30; } return money; } } /** * 假日折扣 * 需要大于100 */ public class HolidayDiscount implements Discount{ @Override public int calculate(int money) { if (money > 100){ return money - 10; } return money; } } /** * 新用戶減免 * 但是也需要大于100 */ public class NewerDiscount implements Discount{ @Override public int calculate(int money) { if (money>100){ return money-20; } return money; } } /** * 第二單8折優(yōu)惠 */ public class SecondDiscount implements Discount { @Override public int calculate(int money) { Double balance = money * 0.8; return balance.intValue(); } } public static void main(String[] args) { List<Fruit> products = new ArrayList(); products.add(StaticFactory.getFruitApple()); products.add(StaticFactory.getFruitBanana()); products.add(StaticFactory.getFruitOrange()); ShoppingCart cart = new CartShopping(products); /*注入優(yōu)惠方案*/ cart.setDiscount(new FullDiscount()); cart.submitOrder(); }
5.策略設(shè)計模式的應(yīng)用場景
在程序設(shè)計中,通常在以下幾種情況中使用策略模式較多:
- 一個系統(tǒng)需要動態(tài)地在幾種算法中選擇一種時,可將每個算法封裝到策略類中。
- 一個類定義了多種行為,并且這些行為在這個類的操作中以多個條件語句的形式出現(xiàn),可將每個條件分支移入它們各自的策略類中以代替這些條件語句。
- 系統(tǒng)中各算法彼此完全獨立,且要求對客戶隱藏具體算法的實現(xiàn)細節(jié)時。
- 系統(tǒng)要求使用算法的客戶不應(yīng)該知道其操作的數(shù)據(jù)時,可使用策略模式來隱藏與算法相關(guān)的數(shù)據(jù)結(jié)構(gòu)。
- 多個類只區(qū)別在表現(xiàn)行為不同,可以使用策略模式,在運行時動態(tài)選擇具體要執(zhí)行的行為。
到此這篇關(guān)于Java行為型設(shè)計模式之策略模式詳解的文章就介紹到這了,更多相關(guān)Java策略模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決mysql字符串類型的數(shù)字排序出錯:cast(year as signed)
這篇文章主要介紹了解決mysql字符串類型的數(shù)字排序出錯問題 :cast(year as signed),如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08HashMap工作原理_動力節(jié)點Java學(xué)院整理
這篇文章主要介紹了HashMap工作原理_動力節(jié)點Java學(xué)院整理,需要的朋友可以參考下2017-04-04SpringBoot修改子模塊Module的jdk版本的方法 附修改原因
這篇文章主要介紹了SpringBoot修改子模塊Module的jdk版本的方法 附修改原因,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04學(xué)習(xí)java編程后可以走哪些職業(yè)道路
在本篇文章里給大家介紹了關(guān)于學(xué)習(xí)java后的職業(yè)道路,以及需要學(xué)習(xí)的相關(guān)知識內(nèi)容,有興趣的朋友們可以跟著學(xué)習(xí)下。2022-11-11java實現(xiàn)數(shù)字轉(zhuǎn)換人民幣中文大寫工具
這篇文章主要為大家詳細介紹了java實現(xiàn)數(shù)字轉(zhuǎn)換人民幣中文大寫工具,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04