【設計模式】策略模式(政策(Policy)模式)

策略模式(Strategy Pattern)詳解


一、策略模式簡介

策略模式(Strategy Pattern) 是一種 行為型設計模式(對象行為型模式),它定義了一系列算法,并將每一個算法封裝起來,使它們可以互相替換,獨立于使用它們的客戶端。

又稱為政策(Policy)模式
每一個封裝算法的類稱之為策略(Strategy)類
策略模式提供了一種可插入式(Pluggable)算法的實現方案。

你可以把它理解為:

“一個工具箱里有多個工具,你可以在不同場景下選擇不同的工具來完成任務。”

在策略模式中,這些“工具”就是各種具體的策略類,而“任務執行者”則是使用這些策略的對象。

旅游出行方式
在這里插入圖片描述
實現某個目標的途徑不止一條,可根據實際情況選擇一條合適的途徑。

軟件開發
多種算法,例如排序、查找、打折等
使用硬編碼(Hard Coding)實現將導致系統違背開閉原則,擴展性差,且維護困難
可以定義一些獨立的類來封裝不同的算法,每一個類封裝一種具體的算法 —> 策略類

public class Context
{……public void algorithm(String type)  {......if(type == "strategyA"){//算法A}else if(type == "strategyB"){//算法B}else if(type == "strategyC"){//算法C}......}……
} 

策略模式包含以下3個角色
Context(環境類)
Strategy(抽象策略類)
ConcreteStrategy(具體策略類)

在這里插入圖片描述


二、解決的問題類型

策略模式主要用于解決以下問題:

  • 同一行為具有多種實現方式:比如支付方式可以是支付寶、微信、銀行卡等。
  • 避免大量的 if-else 或 switch-case 判斷邏輯:提高代碼可讀性和擴展性。
  • 希望在運行時動態切換算法或行為:比如根據用戶等級選擇不同的折扣策略。

三、使用場景

場景示例
不同支付方式支付寶、微信、銀聯等
折扣計算普通會員、VIP會員、超級會員等不同折扣規則
物流配送順豐、京東、德邦等不同物流策略
游戲角色技能角色攻擊方式隨武器變化而變化

四、核心結構

策略模式通常包含三個部分:

  1. 策略接口(Strategy):定義所有策略共有的行為。
  2. 具體策略類(Concrete Strategies):實現接口中的具體行為。
  3. 上下文類(Context):持有一個策略接口的引用,負責調用策略方法。

五、實際代碼案例(Java)

我們以電商系統中的“支付方式”為例,演示策略模式的使用。

1. 定義策略接口

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

2. 實現具體策略類

// 微信支付策略
public class WeChatPay implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("WeChat Pay: $" + amount);}
}// 支付寶支付策略
public class AliPay implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("AliPay: $" + amount);}
}// 銀行卡支付策略
public class BankCardPay implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("Bank Card Pay: $" + amount);}
}

3. 創建上下文類

// 上下文類:支付環境
public class ShoppingCart {private PaymentStrategy paymentStrategy;// 設置策略public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}// 使用策略進行支付public void checkout(int amount) {if (paymentStrategy == null) {throw new IllegalStateException("Please select a payment strategy.");}paymentStrategy.pay(amount);}
}

4. 客戶端測試類

public class Client {public static void main(String[] args) {ShoppingCart cart = new ShoppingCart();// 使用微信支付cart.setPaymentStrategy(new WeChatPay());cart.checkout(100);// 切換為支付寶支付cart.setPaymentStrategy(new AliPay());cart.checkout(200);// 切換為銀行卡支付cart.setPaymentStrategy(new BankCardPay());cart.checkout(300);}
}

輸出結果:

WeChat Pay: $100
AliPay: $200
Bank Card Pay: $300

典型代碼(C++)

典型的抽象策略類代碼

abstract class AbstractStrategy
{public abstract void Algorithm(); //聲明抽象算法
}

典型的抽象策略類代碼

class ConcreteStrategyA : AbstractStrategy 
{
//算法的具體實現
public override void Algorithm() 
{//算法A
}
}

典型的環境類代碼

class Context
{private AbstractStrategy strategy; //維持一個對抽象策略類的引用public void SetStrategy(AbstractStrategy strategy) {this.strategy = strategy;}//調用策略類中的算法public void Algorithm() {strategy.Algorithm();}
}

典型的客戶端代碼片段

……
Context context = new Context();
AbstractStrategy strategy;
strategy = new ConcreteStrategyA(); //可在運行時指定類型,通過配置文件和反射機制實現
context.SetStrategy(strategy);
context.Algorithm();
……
其他案例
  1. 某軟件公司為某電影院開發了一套影院售票系統,在該系統中需要為不同類型的用戶提供不同的電影票打折方式,具體打折方案如下:
    (1) 學生憑學生證可享受票價8折優惠。
    (2) 年齡在10周歲及以下的兒童可享受每張票減免10元的優惠(原始票價需大于等于20元)。
    (3) 影院VIP用戶除享受票價半價優惠外還可進行積分,積分累計到一定額度可換取電影院贈送的獎品。
    該系統在將來可能還要根據需要引入新的打折方式。現使用策略模式設計該影院售票系統的打折方案

在這里插入圖片描述

  1. 排序策略
    某系統提供了一個用于對數組數據進行操作的類,該類封裝了對數組的常見操作,如查找數組元素、對數組元素進行排序等。現以排序操作為例,使用策略模式設計該數組操作類,使得客戶端可以動態地更換排序算法,可以根據需要選擇冒泡排序或選擇排序或插入排序,也能夠靈活地增加新的排序算法。

在這里插入圖片描述

  1. 旅游出行策略
    旅游出行方式可以有多種,如可以乘坐飛機旅游,也可以乘火車旅游,如果有興趣自行車游也是一種極具樂趣的出行方式。不同的旅游出行方式有不同的實現過程,客戶根據自己的需要選擇一種合適的旅游方式。在本實例中我們用策略模式來模擬這一過程。

在這里插入圖片描述

六、優缺點分析

優點描述
? 解耦將算法和使用它的對象分離,降低耦合度
? 易于擴展新增策略只需新增類,符合開閉原則。提供了對開閉原則的完美支持,用戶可以在不修改原有系統的基礎上選擇算法或行為,也可以靈活地增加新的算法或行為
? 運行時可切換策略提供更高的靈活性
? 減少冗長的條件判斷語句替代 if-else 或 switch-case 結構
其他提供了管理相關的算法族的辦法,提供了一種可以替換繼承關系的辦法,提供了一種算法的復用機制,不同的環境類可以方便地復用策略類
缺點描述
? 增加類數量每個策略對應一個類,可能導致類膨脹,將造成系統產生很多具體策略類
? 需要對外暴露策略類客戶端需了解所有策略才能選擇使用哪個
? 不適合簡單分支邏輯如果策略種類很少,使用策略模式反而增加了復雜度
其他無法同時在客戶端使用多個策略類

七、與其他模式對比(補充)

模式名稱目標
模板方法模式在父類定義算法骨架,子類實現具體步驟
責任鏈模式請求在鏈上傳遞,每個節點決定是否處理請求
策略模式多種算法/行為封裝成策略,運行時可切換

八、最終小結

策略模式是一種非常實用的設計模式,適用于那些具有多種實現方式、需要靈活切換的業務邏輯。它通過將行為抽象為接口和實現類,使得程序更加清晰、易維護、易擴展。

在開發電商系統、支付模塊、權限控制、游戲邏輯等項目中,策略模式都能發揮重要作用。


📌 一句話總結:

策略模式就像“萬能遙控器”,可以自由切換不同的功能模塊,讓程序更靈活、更具適應性。


? 推薦使用方式:

  • 對于固定的行為,但實現方式多樣的場景優先考慮策略模式;
  • 可結合工廠模式統一創建策略實例,提升管理效率;
  • 使用 Lambda 表達式簡化簡單策略的實現(如 Java 8+);

部分內容由AI大模型生成,注意識別!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914410.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914410.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914410.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

用TensorFlow進行邏輯回歸(二)

邏輯回歸的例子 邏輯回歸是經典的分類算法。為了簡單,我們考慮二分類。這意味著,我們要處理識別二個分類的問題,我們的標簽為 0 或 1。 我們要一個與線性回歸不同的激活函數,不同的損失函數,神經元的輸出略有不同。我們…

Java設計模式之行為型模式(命令模式)介紹與說明

一、核心定義與目標 命令模式通過對象化請求,將操作的具體實現細節隱藏在命令對象中,使得調用者(Invoker)無需直接與接收者(Receiver)交互,僅需通過命令對象間接調用。這種解耦設計支持以下功能…

【深度學習新浪潮】xAI新發布的Grok4有什么看點?

Grok4作為馬斯克旗下xAI公司最新發布的旗艦AI模型,其核心看點和評測要點可總結如下: 一、Grok4的核心看點 學術推理能力全面超越人類博士水平 在「人類終極考試」(HLE)中,Grok4基礎版正確率達25.4%,啟用工具后飆升至44.4%,遠超Gemini 2.5 Pro(21.6%)和OpenAI o3(20.…

觀成科技:基于自監督學習技術的惡意加密流量檢測方案

1.前言當前,隨著加密協議技術的廣泛應用,互聯網用戶的個人流量隱私得到了有效保護,但與此同時也衍生出一系列安全問題。由于加密流量在傳輸過程中無法被解密,導致傳輸信息呈現“黑盒化”特征,這為惡意攻擊者利用加密流…

通用定時器GPT

目錄 GPT核心特性 GPT 計數器操作模式 重啟模式 自由運行模式 GPT時鐘源 GPT框圖 輸入捕獲:測量外部信號的高電平脈沖寬度 輸出比較:生成 1kHz PWM 波 GPT模塊外部引腳復用與功能映射表 GPT使用注意事項 GPT Memory Map GPT寄存器 GPTx_CR寄存…

#oda0095. 字符串通配符【B卷 100分】-字符串

題目描述問題描述:在計算機中,通配符一種特殊語法,廣泛應用于文件搜索、數據庫、正則表達式等領域。現要求各位實現字符串通配符的算法。要求:實現如下2個通配符:* :匹配0個或以上的字符(注&…

面向對象設計原則

面向對象:是一種編程思想,面向過程是關注實現的步驟,每個步驟定義一個函數,調用函數執行即可。面向對象關注的是誰來執行,把具有相同屬性和行為的一類事物進行抽象成類,然后再通過實例化出一個個具體的對象…

Hyperledger Fabric深入解讀:企業級區塊鏈的架構、應用與未來

一、引言:企業級區塊鏈的標桿Hyperledger Fabric是Linux基金會主導的開源項目,專為企業級應用設計,以模塊化架構、許可鏈機制和隱私保護為核心,廣泛應用于金融、供應鏈、醫療等領域。相較于公有鏈(如以太坊&#xff09…

從0開始學習R語言--Day45--Hausman檢驗

當我們在探究數據本身是否和變量相關時,往往都會對這兩者進行回歸分析,控制一下變量來看看趨勢走向。但其實在分析前,我們可以先嘗試做Hausman檢驗,這可以幫助我們判斷數據的變化到底是因為變量不一樣了還是因為自己的個體效應所以…

閑庭信步使用圖像驗證平臺加速FPGA的開發:第九課——圖像插值的FPGA實現

(本系列只需要modelsim即可完成數字圖像的處理,每個工程都搭建了全自動化的仿真環境,只需要雙擊top_tb.bat文件就可以完成整個的仿真,大大降低了初學者的門檻!!!!如需要該系列的工程…

Android事件分發機制完整總結

一、核心概念事件分發的本質Android事件分發采用責任鏈模式,事件從Activity開始,依次經過ViewGroup和View。整個機制只有一個入口:dispatchTouchEvent方法。onInterceptTouchEvent和onTouchEvent都不是獨立的事件入口,而是被dispa…

【論文閱讀】AdaReasoner: Adaptive Reasoning Enables More Flexible Thinking

AdaReasoner: Adaptive Reasoning Enables More Flexible Thinking3. AdaReasoner3.1 動機3.2 問題定義3.3 動作選擇過程3.3.1 動作空間定義3.3.2 動作選擇3.4 探索策略3.5 強化學習訓練3.5.1 訓練算法3.5.2 目標函數3.5.3 損失函數AdaReasoner: Adaptive Reasoning Enables Mo…

深入了解Modbus TCP:工業通信的“通用語言”

目錄 簡介一、Modbus TCP的“前世今生”二、Modbus TCP的核心特點三、Modbus TCP的工作原理1. 報文結構2. 功能碼四、Modbus TCP的應用場景五、使用Modbus TCP的注意事項六、總結簡介 在工業自動化的世界里,不同設備之間的“對話”至關重要。從PLC(可編程邏輯控制器)到傳感…

基于Selenium和FFmpeg的全平臺短視頻自動化發布系統

一、項目背景與概述在當今短視頻營銷盛行的時代,許多企業和個人需要同時管理多個短視頻平臺賬號。手動上傳視頻到抖音、快手、小紅書等平臺不僅效率低下,而且容易出錯。本文將介紹一個基于Python的自動化短視頻處理與發布系統,它能夠&#xf…

技術演進中的開發沉思-31 MFC系列:類層次結構

提及MFC,不得不說他的類層次。如果把 MFC 框架比作是座精密的鐘表,那類層次結構便是其內部咬合的齒輪組。每個類都有明確的 “家族地位”,既繼承著先輩的本領,又發展出獨特的專長。這種層級分明的設計,讓 Windows 編程…

2023.05.06 更新前端面試問題總結(12道題)

2023.05.04 - 2023.05.06 更新前端面試問題總結(12道題) 獲取更多面試相關問題可以訪問 github 地址: https://github.com/pro-collection/interview-question/issues gitee 地址: https://gitee.com/yanleweb/interview-question/issues 目錄&#xff1…

【網絡】Linux 內核優化實戰 - net.ipv4.tcp_keepalive_intvl

目錄1. TCP Keep-Alive 機制回顧2. 參數作用3. 參數取值與影響4. 使用場景與建議5. 相關參數6. 如何配置該參數臨時生效(重啟后失效):永久生效(需重啟或重載配置):7. 性能優化建議8. 監控與故障排查net.ipv…

20250710解決KickPi的K7的SDK編譯異常:rk3576-android14.0-25250704.tar.gz【降低BUILD_JOBS】

20250710解決KickPi的K7的SDK編譯異常:rk3576-android14.0-25250704.tar.gz【降低BUILD_JOBS】 2025/7/10 20:59緣起:KickPi的K7的SDK編譯異常:rk3576-android14.0-25250704.tar.gzZ:\14TB\SDK\rk3576_data\1-SDK軟件源碼\Android14\20250704…

《Java EE與中間件》實驗一 基于MyBatis的留言本

目 錄 一、實驗目的和要求 1、實驗目的 2、實驗要求 二、實驗實現思路及步驟 1、實驗思路 2、實驗步驟 3、實驗方案 三、主要開發工具 四、實驗效果及實現代碼 1、留言本數據庫構建實現 (1)建立javaee-project數據庫 (2&#xf…

ARM匯編編程(AArch64架構) - 第14課:安全擴展(ARM TrustZone)

目錄1. TrustZone基礎概念1.1 安全擴展架構1.2 關鍵組件2. 世界切換機制2.1 狀態切換流程2.2 關鍵寄存器配置3. SMC調用實現3.1 調用規范3.2 完整調用流程4. 實戰練習4.1 實驗:實現雙世界通信4.2 調試技巧1. TrustZone基礎概念 1.1 安全擴展架構 startuml rectang…