日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

一文搞懂設(shè)計(jì)模式—策略模式

來源: 責(zé)編: 時(shí)間:2024-02-01 12:52:11 222觀看
導(dǎo)讀在軟件開發(fā)中,經(jīng)常會(huì)遇到需要根據(jù)不同的條件來實(shí)現(xiàn)不同行為的場(chǎng)景。這種場(chǎng)景下,策略模式(Strategy Pattern)就是一種非常有用的設(shè)計(jì)模式。策略模式屬于行為型模式,允許我們定義一系列算法,并將其封裝在獨(dú)立的策略類中,使得它

在軟件開發(fā)中,經(jīng)常會(huì)遇到需要根據(jù)不同的條件來實(shí)現(xiàn)不同行為的場(chǎng)景。這種場(chǎng)景下,策略模式(Strategy Pattern)就是一種非常有用的設(shè)計(jì)模式。w4828資訊網(wǎng)——每日最新資訊28at.com

策略模式屬于行為型模式,允許我們定義一系列算法,并將其封裝在獨(dú)立的策略類中,使得它們可以互相替換。通過使用策略模式,我們能夠靈活地選擇和切換不同的算法,而無需修改原有的代碼,替代?量 if else 的邏輯。w4828資訊網(wǎng)——每日最新資訊28at.com

使用場(chǎng)景

策略模式通常在以下情況下被使用:w4828資訊網(wǎng)——每日最新資訊28at.com

  • 當(dāng)存在多種實(shí)現(xiàn)方式,且需要在運(yùn)行時(shí)動(dòng)態(tài)選擇具體實(shí)現(xiàn)時(shí),策略模式非常有用。例如,一個(gè)購物應(yīng)用可能需要根據(jù)用戶的會(huì)員等級(jí)來計(jì)算折扣,不同等級(jí)對(duì)應(yīng)不同的計(jì)算方式,這時(shí)就可以使用策略模式來實(shí)現(xiàn)。
  • 當(dāng)存在一組類似的行為,只是實(shí)現(xiàn)細(xì)節(jié)略有不同,但又不希望通過繼承來添加新的子類時(shí),策略模式也很適用。它將這組行為封裝在獨(dú)立的策略類中,并通過委托的方式在上下文對(duì)象中使用。

例如:w4828資訊網(wǎng)——每日最新資訊28at.com

  • 支付方式選擇:一個(gè)電子商務(wù)平臺(tái)可以根據(jù)用戶的選擇來使用不同的支付策略,例如信用卡支付、支付寶支付、微信支付等。
  • 排序算法選擇:一個(gè)排序工具可以根據(jù)用戶的需求選擇不同的排序算法,例如快速排序、歸并排序等。
  • 數(shù)據(jù)驗(yàn)證:一個(gè)表單驗(yàn)證工具可以根據(jù)不同的驗(yàn)證規(guī)則采用不同的驗(yàn)證策略,例如長度驗(yàn)證、格式驗(yàn)證等。

這些只是策略模式的一些例子,實(shí)際應(yīng)用場(chǎng)景非常豐富。通過使用策略模式,我們可以將算法或行為與具體的業(yè)務(wù)邏輯解耦,使得系統(tǒng)更加靈活和可擴(kuò)展。w4828資訊網(wǎng)——每日最新資訊28at.com

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

在策略模式中,有三個(gè)核心角色:上下文(Context)、策略接口(Strategy)和具體策略類(Concrete Strategy)。w4828資訊網(wǎng)——每日最新資訊28at.com

  • 上下文(Context):封裝了具體策略的執(zhí)行邏輯,提供給客戶端使用的接口。上下文通常包含一個(gè)指向策略接口的引用,用于調(diào)用具體策略的方法。
  • 策略接口(Strategy):定義了一組算法或行為的公共接口,所有具體策略都必須實(shí)現(xiàn)該接口。
  • 具體策略類(Concrete Strategy):實(shí)現(xiàn)了策略接口,提供了具體的算法或行為。

下面我們來實(shí)現(xiàn)一下策略模式:w4828資訊網(wǎng)——每日最新資訊28at.com

步驟 1

創(chuàng)建策略接口。w4828資訊網(wǎng)——每日最新資訊28at.com

//策略接口public interface PaymentStrategy {    void pay(double amount);}

步驟2

創(chuàng)建策略接口實(shí)現(xiàn)類。w4828資訊網(wǎng)——每日最新資訊28at.com

//具體策略類public class CreditCardPayment implements PaymentStrategy {    public void pay(double amount) {        System.out.println("使用信用卡支付:" + amount);        // 具體的支付邏輯    }}
public class WeChatPay implements PaymentStrategy {    public void pay(double amount) {        System.out.println("使用微信支付:" + amount);        // 具體的支付邏輯    }}

注意:在實(shí)際項(xiàng)目中,我們一般通過工廠方法模式來實(shí)現(xiàn)策略類的聲明。w4828資訊網(wǎng)——每日最新資訊28at.com

實(shí)現(xiàn)關(guān)系如下:w4828資訊網(wǎng)——每日最新資訊28at.com

圖片圖片w4828資訊網(wǎng)——每日最新資訊28at.com

步驟 3

創(chuàng)建 Context 類。w4828資訊網(wǎng)——每日最新資訊28at.com

// 上下文類public class PaymentContext {    private PaymentStrategy paymentStrategy;        public PaymentContext(PaymentStrategy paymentStrategy) {        this.paymentStrategy = paymentStrategy;    }        public void pay(double amount) {        paymentStrategy.pay(amount);    }}

調(diào)用一下:w4828資訊網(wǎng)——每日最新資訊28at.com

// 使用示例public class Main {    public static void main(String[] args) {        PaymentStrategy strategy = new CreditCardPayment();        PaymentContext context = new PaymentContext(strategy);        context.pay(100.0);                strategy = new WeChatPay();        context = new PaymentContext(strategy);        context.pay(200.0);    }}

輸出:w4828資訊網(wǎng)——每日最新資訊28at.com

使用信用卡支付:100.0使用微信支付:200.0

在上面的代碼中,我們定義了一個(gè) PaymentStrategy 接口作為策略接口,兩個(gè)具體的策略類 CreditCardPayment 和 WeChatPay 實(shí)現(xiàn)了該接口。然后,我們創(chuàng)建了一個(gè) PaymentContext 上下文對(duì)象,并根據(jù)需要傳入不同的策略實(shí)例進(jìn)行支付操作。w4828資訊網(wǎng)——每日最新資訊28at.com

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

策略模式的優(yōu)點(diǎn)包括:w4828資訊網(wǎng)——每日最新資訊28at.com

  • 松耦合:策略模式將不同的策略封裝在獨(dú)立的類中,與上下文對(duì)象解耦,增加了代碼的靈活性和可維護(hù)性。
  • 易于擴(kuò)展:可以通過添加新的策略類來擴(kuò)展系統(tǒng)的功能,無需修改現(xiàn)有代碼。
  • 符合開閉原則:對(duì)于新的策略,無需修改上下文對(duì)象,只需要實(shí)現(xiàn)新的策略接口即可。

策略模式的缺點(diǎn)包括:w4828資訊網(wǎng)——每日最新資訊28at.com

  • 類數(shù)量增多:每個(gè)具體策略都需要一個(gè)獨(dú)立的類,如果策略較多,將導(dǎo)致類的數(shù)量增加。
  • 上層必須知道所有策略類:上層模塊必須知道有哪些策略,并選擇合適的策略進(jìn)行使用,這與迪米特法則是相違背的,我只是想使用了一個(gè)策略,我憑什么就要了解這個(gè)策略呢?那要你的封裝類還有什么 意義?這是原裝策略模式的一個(gè)缺點(diǎn)。

注意事項(xiàng): 如果一個(gè)系統(tǒng)的策略多于四個(gè),就需要考慮使用混合模式,解決策略類膨脹的問題,否則日后的系統(tǒng)維護(hù)就會(huì)成為一個(gè)燙手山芋。w4828資訊網(wǎng)——每日最新資訊28at.com

策略模式優(yōu)化

使用Map取消 Context 類

我們可以將策略實(shí)現(xiàn)類放進(jìn) Map 中,根據(jù) key 去選擇具體的策略,就不必事先定義 Context 類。w4828資訊網(wǎng)——每日最新資訊28at.com

public static void main(String[] args) {        Map<String, PaymentStrategy> map=new HashMap<>();        map.put("CREDIT_CARD", new CreditCardPayment());        map.put("WECHAT_PAY",new WeChatPay());        map.get("CREDIT_CARD").pay(100.0);        map.get("WECHAT_PAY").pay(200.0);    }

策略枚舉解決策略類膨脹

策略枚舉可以解決策略類過多的問題。w4828資訊網(wǎng)——每日最新資訊28at.com

我們對(duì)原裝的策略模式進(jìn)行改造,把原有定義在抽象策略中的方法移植到枚舉中,讓枚舉成員成為一個(gè)具體策略。w4828資訊網(wǎng)——每日最新資訊28at.com

@Slf4jpublic enum PaymentStrategyEnum {    CREDIT_CARD {        @Override        public void pay(double amount) {            log.info("使用信用卡支付:" + amount);            // 具體的支付邏輯        }    },    WECHAT_PAY {        @Override        public void pay(double amount) {            log.info("使用微信支付:" + amount);            // 具體的支付邏輯        }            };    public abstract void pay(double amount);}

在上面的代碼中,我們定義了一個(gè)枚舉類型 PaymentStrategy,其中包含兩個(gè)枚舉常量 CREDIT_CARD 和 WECHAT_PAY。每個(gè)枚舉常量都重寫了 pay() 方法,用于具體的支付邏輯。w4828資訊網(wǎng)——每日最新資訊28at.com

// 使用示例public static void main(String[] args) {        Map<String, PaymentStrategyEnum> map=new HashMap<>();        map.put("CREDIT_CARD",  PaymentStrategyEnum.CREDIT_CARD);        map.put("WECHAT_PAY", PaymentStrategyEnum.WECHAT_PAY);        map.get("CREDIT_CARD").pay(100.0);        map.get("WECHAT_PAY").pay(200.0);    }

注意:策略枚舉是一個(gè)非常優(yōu)秀和方便的模式,但是它受枚舉類型的限制,每個(gè)枚舉項(xiàng)都是 public、final、static 的,擴(kuò)展性受到了一定的約束,因此在系統(tǒng)開發(fā)中,策略枚舉一般擔(dān)當(dāng)不經(jīng)常發(fā)生變化的角色。w4828資訊網(wǎng)——每日最新資訊28at.com

SpringBoot中的策略模式

SpringBoot中使用策略模式更加方便:w4828資訊網(wǎng)——每日最新資訊28at.com

public interface Test {    void print(String name);}
@Service("testA")@Slf4jpublic class TestA implements Test{    @Override    public void print(String name) {        log.info("實(shí)現(xiàn)類A"+name);    }}
@Service("testB")@Slf4jpublic class TestB implements Test{    @Override    public void print(String name) {        log.info("實(shí)現(xiàn)類B"+name);    }}

使用的時(shí)候 @Autowired 或者 @Resource 即可,SpringBoot會(huì)幫我們把實(shí)現(xiàn)類自動(dòng)注入注入Map。w4828資訊網(wǎng)——每日最新資訊28at.com

@Resourceprivate Map<String,Test> map;
Test test = map.get("你想拿出的具體策略類");test.print("hello world");

總結(jié)

策略模式是一種強(qiáng)大而靈活的設(shè)計(jì)模式,它可以幫助我們處理不同的算法或行為,并使系統(tǒng)更具可維護(hù)性和擴(kuò)展性。通過封裝具體的策略類和使用上下文對(duì)象,我們可以輕松地選擇和切換不同的策略,而無需修改現(xiàn)有的代碼。w4828資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-70477-0.html一文搞懂設(shè)計(jì)模式—策略模式

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 深入理解Java線程池,剖析LinkedBlockingQueue源碼實(shí)現(xiàn)

下一篇: Java中的并發(fā)編程模型及其應(yīng)對(duì)策略

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 龙陵县| 枞阳县| 固原市| 东源县| 安阳县| 保亭| 共和县| 板桥市| 台中县| 海林市| 南通市| 阿克苏市| 柯坪县| 广饶县| 房产| 顺昌县| 桃园县| 台东市| 七台河市| 泸州市| 宣化县| 富阳市| 鹿邑县| 隆昌县| 吐鲁番市| 拜城县| 绵阳市| 昌图县| 松溪县| 商都县| 七台河市| 拜城县| 丹棱县| 嘉鱼县| 石门县| 牡丹江市| 天水市| 高州市| 孟州市| 北川| 勃利县|