Java中策略設(shè)計(jì)模式的實(shí)現(xiàn)及應(yīng)用場(chǎng)景
介紹
Java策略模式(Strategy Pattern)是一種行為設(shè)計(jì)模式,它允許再運(yùn)行時(shí)動(dòng)態(tài)選擇算法的行為.策略模式通過將算法封裝在可互換的策略對(duì)象中,使得客戶端代碼能夠輕松地切換算法,而無需修改原始代碼.在策略模式中,每個(gè)算法都被實(shí)現(xiàn)為一個(gè)單獨(dú)的策略類,這些策略類都實(shí)現(xiàn)了相同的接口,從而允許它們?cè)谶\(yùn)行時(shí)互相替換.
在Java中,可以使用接口或抽象類來定義策略接口.然后對(duì)于每個(gè)算法,都可以創(chuàng)建一個(gè)具體的實(shí)現(xiàn)類來實(shí)現(xiàn)這個(gè)接口.客戶端代碼可以通過將不同的策略對(duì)象傳遞給上下文對(duì)象來選擇不同的算法.
Java策略模式通常包括以下三種角色:
- Context(上下文):是策略模式中的核心類,用來管理具體策略實(shí)現(xiàn)類的創(chuàng)建,配置和執(zhí)行,以及在運(yùn)行時(shí)動(dòng)態(tài)地選擇具體的策略實(shí)現(xiàn)類.
- Strategy(策略):是一個(gè)接口或抽象類,定義了策略實(shí)現(xiàn)類的通用方法和屬性,具體策略實(shí)現(xiàn)類必須實(shí)現(xiàn)這些方法和屬性.
- ConcreteStrategy(具體策略):是策略接口的實(shí)現(xiàn)類,根據(jù)具體業(yè)務(wù)需求實(shí)現(xiàn)了策略接口定義的方法和屬性.可以又多個(gè)具體策略實(shí)現(xiàn)類,Context類在運(yùn)行時(shí)根據(jù)需要?jiǎng)討B(tài)地選擇具體的策略實(shí)現(xiàn)類.
實(shí)現(xiàn)
支付策略接口(Strategy)
public interface PaymentStrategy { /** * 支付 * * @param amount */ void pay(double amount); }
微信支付和支付寶支付(ConcreteStrategy)
public class WechatPayment implements PaymentStrategy { private String username; private String password; public WechatPayment(String username, String password) { this.username = username; this.password = password; } /** * 支付 * * @param amount */ @Override public void pay(double amount) { System.out.println("微信支付:" + amount + "元"); } } public class AliPayment implements PaymentStrategy{ private String username; private String password; public AliPayment(String username, String password) { this.username = username; this.password = password; } /** * 支付 * * @param amount */ @Override public void pay(double amount) { System.out.println("支付寶支付:" + amount + "元"); } }
購(gòu)物車類(Context)
public class ShoppingCart { private List<Item> itemList; private PaymentStrategy paymentStrategy; public ShoppingCart() { itemList = new ArrayList<>(); } public void setPaymentStrategy(PaymentStrategy paymentStrategy) { this.paymentStrategy = paymentStrategy; } public void addItem(Item item){ itemList.add(item); } public void removeItem(Item item){ itemList.remove(item); } public double calculateTotal(){ return itemList.stream().mapToDouble(Item::getPrice).sum(); } public void pay(){ paymentStrategy.pay(calculateTotal()); } }
商品類
@Data public class Item { private String name; private double price; public Item(String name, double price) { this.name = name; this.price = price; } }
測(cè)試
public class Demo { public static void main(String[] args) { ShoppingCart shoppingCart = new ShoppingCart(); Item item1 = new Item("item1",10); Item item2 = new Item("item2",10); shoppingCart.addItem(item1); shoppingCart.addItem(item2); shoppingCart.setPaymentStrategy(new AliPayment("aliPayUsername","aliPayPassword")); shoppingCart.pay(); shoppingCart.setPaymentStrategy(new WechatPayment("wechatUsername","wechatPassword")); shoppingCart.pay(); } }
上面代碼演示了一個(gè)簡(jiǎn)單的策略模式實(shí)現(xiàn).我們定義了一個(gè)PaymentStrategy接口,它表示所有支付方式的共同操作.我們還定義了兩個(gè)實(shí)現(xiàn)該接口的具體類AliPayment和WechatPayment,它們分別表示使用支付寶和微信支付的操作.我們還定義了一個(gè)ShoppingCart類,該類使用PaymentStrategy接口來表示支付方式,并根據(jù)需要切換實(shí)際的支付方式.
在我們的Demo類中,我們創(chuàng)建了一個(gè)ShoppingCart對(duì)象,并添加了兩個(gè)Item對(duì)象,我們?nèi)缓筮x擇使用AliPayment進(jìn)行支付,并調(diào)用pay()方法.我們接下來又選擇使用WechatPayment進(jìn)行支付,并再次調(diào)用pay()方法.
這樣,我們就可以輕松地在不同的支付方式之間進(jìn)行切換,并根據(jù)需要添加新的支付方式.
總結(jié)
優(yōu)點(diǎn)
- 容易擴(kuò)展和維護(hù):通過定義一個(gè)抽象的策略接口,可以方便地增加新的策略實(shí)現(xiàn)類,而不需要修改現(xiàn)有代碼
- 易于替換算法:在運(yùn)行時(shí)可以動(dòng)態(tài)地切換算法實(shí)現(xiàn),無需修改客戶端代碼
- 降低了耦合度:客戶端只需要知道策略接口即可,不需要知道具體的策略實(shí)現(xiàn)類
- 提高了復(fù)用性:不同的策略實(shí)現(xiàn)類可以在多個(gè)場(chǎng)景下復(fù)用
缺點(diǎn)
- 增加了類的數(shù)量:為每個(gè)具體策略都定義了一個(gè)實(shí)現(xiàn)類,可能會(huì)增加類的數(shù)量.
- 客戶端必須知道策略接口:客戶端需要知道具體的策略接口,才能正確使用策略實(shí)現(xiàn)類.
- 運(yùn)行時(shí)開銷較大:在運(yùn)行時(shí),需要根據(jù)不同的策略實(shí)現(xiàn)類進(jìn)行判斷和選擇,會(huì)帶來一定的開銷
應(yīng)用場(chǎng)景
- 有多個(gè)相似的類,只有行為有差異的情況下,可以考慮使用策略模式.
- 需要在運(yùn)行時(shí)動(dòng)態(tài)切換算法的情況下,可以使用策略模式.
- 一個(gè)系統(tǒng)需要在不同時(shí)間應(yīng)用不同的業(yè)務(wù)規(guī)則情況下,可以使用策略模式
- 在一個(gè)系統(tǒng)中,有許多類需要根據(jù)某種規(guī)則進(jìn)行排序,查找等操作的情況下,可以使用策略模式.
到此這篇關(guān)于Java中策略設(shè)計(jì)模式的實(shí)現(xiàn)及應(yīng)用場(chǎng)景的文章就介紹到這了,更多相關(guān)Java策略設(shè)計(jì)模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java處理時(shí)間格式CST和GMT轉(zhuǎn)換方法示例
這篇文章主要給大家介紹了關(guān)于Java處理時(shí)間格式CST和GMT轉(zhuǎn)換方法的相關(guān)資料,相信很多小伙伴在時(shí)間格式轉(zhuǎn)換的時(shí)候非常頭疼,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09Spring Boot緩存實(shí)戰(zhàn) Caffeine示例
本篇文章主要介紹了Spring Boot緩存實(shí)戰(zhàn) Caffeine示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02解決MyEclipse出現(xiàn)the user operation is waiting的問題
今天做項(xiàng)目的時(shí)候每次修改代碼保存后都會(huì)跳出一個(gè)框框,然后就有兩個(gè)進(jìn)度條,上面寫the user operation is wating...小編去網(wǎng)上查了查解決了這個(gè)問題,下面跟大家分享一下。2018-04-04SpringBoot整合Mybatis Plus多數(shù)據(jù)源的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot整合Mybatis Plus多數(shù)據(jù)源的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11使用@PathVariable時(shí)候無法將參數(shù)映射到變量中的解決
這篇文章主要介紹了使用@PathVariable時(shí)候無法將參數(shù)映射到變量中的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08