《設計模式》策略模式

1.策略模式定義

策略模式(Strategy Pattern)是一種行為型設計模式,它定義了一組算法,將每個算法封裝起來,并使它們可以相互替換,從而讓算法的變化獨立于使用它的客戶(Client)。

換句話說, 策略模式讓一個類的行為或其算法可以在運行時更改,而不會影響使用該類的代碼。

UML圖:

在這里插入圖片描述

2.策略模式舉例:

業務場景:需要實現一個商場收銀系統,有三種策略,

  1. 正常結賬
  2. 打折
  3. 滿減
    實現業務功能如下:

2.1 代碼設計UML圖如下:

在這里插入圖片描述

2.2 關鍵代碼:

CashContext代碼:和抽象工廠結合,減少耦合。之前客戶端需要了解CashContext和CashSuper兩個類,現在只需要了解CashContext一個類,封裝更好,耦合更小。

public class CashContext {private CashSuper cs;   //聲明一個CashSuper對象//通過構造方法,傳入具體的收費策略public CashContext(int cashType){switch(cashType){case 1:this.cs = new CashNormal();break;case 2:this.cs = new CashRebate(0.8d);break;case 3:this.cs = new CashRebate(0.7d);break;case 4:this.cs = new CashReturn(300d,100d);break;}}public double getResult(double price,int num){//根據收費策略的不同,獲得計算結果return this.cs.acceptCash(price,num);}    
}

CashSuper:


public abstract class CashSuper {public abstract double acceptCash(double price,int num);
}

CashReturn:

public class CashReturn extends CashSuper {private double moneyCondition = 0d; //返利條件private double moneyReturn = 0d;    //返利值//返利收費。初始化時需要輸入返利條件和返利值。//比如“滿300返100”,就是moneyCondition=300,moneyReturn=100public CashReturn(double moneyCondition,double moneyReturn){this.moneyCondition = moneyCondition;this.moneyReturn = moneyReturn;}//計算收費時,當達到返利條件,就原價減去返利值public double acceptCash(double price,int num){double result = price * num;if (moneyCondition>0 && result >= moneyCondition)result = result - Math.floor(result / moneyCondition) * moneyReturn; return result;}}

客戶端代碼:

public class Test {public static void main(String[] args){System.out.println("**********************************************");		System.out.println("策略模式和簡單工廠模式");System.out.println();		int discount = 0; 		//商品折扣模式(1.正常收費 2.打八折 3.打七折)double price = 0d; 		//商品單價int num = 0;			//商品購買數量double totalPrices = 0d;//當前商品合計費用double total = 0d;		//總計所有商品費用Scanner sc = new Scanner(System.in);do {System.out.println("請輸入商品折扣模式(1.正常收費 2.打八折 3.打七折 4.滿300送100):");	discount = Integer.parseInt(sc.nextLine());System.out.println("請輸入商品單價:");	price = Double.parseDouble(sc.nextLine());System.out.println("請輸入商品數量:");	num = Integer.parseInt(sc.nextLine());System.out.println();	if (price>0 && num>0){//根據用戶輸入,將對應的策略對象作為參數傳入CashContext對象中CashContext cc = new CashContext(discount);//通過Context的getResult方法的調用,可以得到收取費用的結果//讓具體算法與客戶進行了隔離totalPrices = cc.getResult(price,num);total = total + totalPrices;System.out.println();	System.out.println("單價:"+ price + "元 數量:"+ num +" 合計:"+ totalPrices +"元");	System.out.println();System.out.println("總計:"+ total+"元");	System.out.println();}}while(price>0 && num>0);System.out.println();System.out.println("**********************************************");}
}

具體運行結果如下:
在這里插入圖片描述

3.策略模式優缺點

? 優點

  • 符合開閉原則(Open-Closed Principle):可以新增新的策略,而不影響已有代碼。
  • 避免冗長的 if-else 語句:如果不使用策略模式,可能會有大量 if-else 邏輯判斷。
  • 支持動態切換:可以在運行時自由更換不同的算法,而不修改原有代碼。
  • 代碼更符合SOLID原則
設計原則策略模式如何符合
單一職責原則(SRP)每個 Strategy 只負責一個算法,職責清晰。
開閉原則(OCP)可以新增策略,而不修改原代碼。
依賴倒置原則(DIP)Context 依賴于 Strategy 接口,而不是具體實現。

? 缺點

  • 增加了代碼復雜度:每個策略都需要定義一個類,當策略過多時,會導致類爆炸。
  • 客戶端需要了解不同策略:調用方需要知道有哪些可用策略,才能正確選擇。

4.策略模式的應用場景

? (1) 算法的可替換性

計算稅收(不同國家稅率)
支付方式(微信支付、支付寶、銀行卡)

? (2) 處理不同格式的文件

解析 JSON、XML、CSV 文件時,使用不同的解析策略。

? (3) AI/機器學習中的優化策略

訓練模型時,可以使用不同的優化算法(SGD、Adam、RMSprop)。

5.策略模式 vs 其他模式

設計模式作用適用場景
策略模式允許在運行時更換不同算法當有多種算法可選,且希望避免 if-else 邏輯。
狀態模式允許對象在不同狀態下表現出不同行為對象的行為依賴于狀態變化,例如訂單狀態。
工廠模式負責創建對象,但不指定其具體實現需要動態創建不同策略對象時,可結合策略模式使用。

6.總結

策略模式核心思想: 定義一組算法,讓它們可以互相替換,而不會影響客戶端代碼。
適用于: 需要多個可替換算法,并希望避免 if-else 邏輯的場景。
優點: 符合開閉原則,可動態切換策略,避免冗長 if-else
缺點: 可能會增加類的數量,使代碼更復雜。

7.參考引用

  • https://juejin.cn/post/7485322373614813220

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

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

相關文章

AWS DMS 深度解析:從遷移任務到復制任務 - 全流程指南與最佳實踐

AWS Database Migration Service (DMS) 是一項強大的云服務,用于在源數據庫和目標數據庫之間安全地遷移數據。其核心優勢在于支持幾乎零停機時間的遷移,這主要歸功于其“變更數據捕獲 (CDC)”功能。理解遷移任務 (Migration Task) 和復制任務 (Replication Task) 的關系與操作…

國企社招 | 中國郵政2025年社會招聘開啟

添加圖片注釋,不超過 140 字(可選) 添加圖片注釋,不超過 140 字(可選) 添加圖片注釋,不超過 140 字(可選) 原文鏈接:“郵”你“政”好 | 廣東郵政2025年社會…

linux添加自啟動

linux添加自啟動 配置步驟: 創建systemd服務文件 sudo nano /etc/systemd/system/tme-vod.service將下面artifact中的內容復制到該文件中。 [Unit] DescriptionTME VOD Service Afternetwork.target[Service] Typesimple Userroot Grouproot WorkingDirectory/data/…

輕量級解決方案:如何高效處理Word轉PDF?

文檔格式轉換時,手動逐個處理總顯得效率低下。它的體積小巧,不到1MB,且無界面設計,運行極簡:將其與Word文件放入同一目錄,雙擊啟動,程序便會自動完成所有文檔的PDF轉換。操作零復雜度&#xff0…

Redis 數據傾斜

Redis 數據傾斜指的是在 Redis 集群模式下,數據(以及相應的訪問請求和負載)在各個分片(Shard)之間分布嚴重不均勻的現象。這會導致部分節點成為熱點或超載,而其他節點資源閑置,最終引發性能瓶頸…

Java基礎-TCP通信(多發多收和一發一收)

目錄 案例要求: 實現思路: 代碼: User:客戶端 Client:服務端 總結: 案例要求: 實現TCP通信的多發多收和一發一收,多發多收去掉各自的while循環就是一發一收,本文只模擬一發一收 實現思路: 客戶端(U…

WinForm 對話框的 Show 與 ShowDialog:阻塞與非阻塞的抉擇

目錄 核心概念:阻塞與非阻塞 Show 與 ShowDialog 的詳細對比 代碼示例:兩種方式的實現差異 使用 Show () 顯示非模態對話框 使用 ShowDialog () 顯示模態對話框 適用場景分析 適合使用 Show () 的場景 適合使用 ShowDialog () 的場景 最佳實踐與…

曉知識: 動態代理與靜態代理的區別

動態代理與靜態代理的區別 代理模式是一種常見的設計模式,用于在不修改原始類的情況下擴展其功能。代理分為靜態代理和動態代理兩種,它們在實現方式、適用場景和靈活性上有顯著差異。 靜態代理 靜態代理在編譯時就已經確定代理類和被代理類的關系。代理類…

Linux系統編程Day9 -- gdb (linux)和lldb(macOS)調試工具

往期內容回顧 Git 教程(初階) 基于Linux系統知識的第一個程序 自動化構建工具-make/Makefile gcc/g編譯及鏈接 Vim工具的使用 Linux常用工具(yum與vim) 一、 Linux 下的調試工具 GDB 一、為什么要學習 GDB? 調試是開發…

數據結構(17)排序(下)

一、計數排序計數排序又稱為鴿巢原理,是對哈希直接定址法的變形應用。操作步驟如下:①統計相同元素出現的次數 ②根據統計的結果將序列回收到原來的序列中比如,現在有一個數組{6,1,2,9,4,2,4,1,4}。該數組中,元素1出現兩次&#…

深度解析 Spring Boot 循環依賴:原理、源碼與解決方案

在 Spring Boot 開發中,循環依賴是一個常見且容易被忽視的技術點。當兩個或多個 Bean 相互引用時,就會形成循環依賴(如 A 依賴 B,B 依賴 A)。初學者往往會困惑:Spring 為什么能自動處理這種看似矛盾的依賴關系?本文將從原理、源碼實現到解決方案,全方位剖析 Spring Boo…

數據庫的基本操作(約束與DQL查詢)

一、約束約束是在表上強制執行的數據規則,用于確保數據的完整性和一致性(1)約束類型MySQL中支持多種約束類型:①主鍵約束(PRIMARY KEY) ②自增約束(AUTO_INCREMENT)③非空約束…

HP Pavilion G6 筆記本安裝Ubuntu開機后自動進入飛行模式的問題解決

問題一臺HP Pavilion G6 筆記本 ,安裝了Ubuntu24.04版本,開機后,直接進入飛行模式,導致無法使用Wifi,且使用fnf10的組合鍵,也無法關閉飛行模式。使用fnf10鍵,可以看到提示顯示飛行模式,但無法關…

LLM:MoE原理與實現探索

文章目錄前言一、Deepseek Moe二. Moe架構1. Expert2. Gate3. MoE Module三、Auxiliary Loss總結前言 MoE(Mixture of Experts) 已經逐漸在LLM中廣泛應用,其工程部署相關目前也有了越來越多的支持,本文主要記錄一下MoE的基本模塊構造與原理。…

基于領域事件驅動的微服務架構設計與實踐

引言:為什么你的微服務總是"牽一發而動全身"? 在復雜的業務系統中,你是否遇到過這樣的困境:修改一個訂單服務,卻導致支付服務異常;調整庫存邏輯,用戶服務開始報錯。這種"蝴蝶效應…

如何使用curl編程來下載文件

libcurl 是一個功能強大的跨平臺網絡傳輸庫,支持多種協議。 本篇來介紹libcul的C語言編程,實現一個文件下載的功能。 1 curl基礎介紹 1.1 核心數據結構 1.1.1 CURL句柄 CURL是libcurl 的核心句柄,每個請求對應一個 CURL 實例,…

大語言模型提示工程與應用:ChatGPT提示工程技術指南

ChatGPT提示工程 學習目標 在本課程中,我們將學習更多關于ChatGPT的最新提示工程技術。 相關知識點 ChatGPT提示工程 學習內容 1 ChatGPT提示工程 ChatGPT是OpenAI研發的新型對話模型,具備多輪對話能力。該模型通過人類反饋強化學習(RLHF)訓練&am…

能力評估:如何系統評估你的技能和經驗

能力評估:如何系統評估你的技能和經驗 作為一名38歲的互聯網研發老兵,你已經積累了豐富的經驗,包括技術深度、項目管理、團隊協作等。但能力評估不是一次性事件,而是持續過程,幫助你識別優勢、短板,并為職業…

鴻蒙開發中所有自定義裝飾器的完整案例解析--涵蓋 16 個核心裝飾器的詳細用法和實戰場景

以下是鴻蒙開發中 所有自定義裝飾器的完整案例解析 和 終極總結指南,涵蓋 16 個核心裝飾器的詳細用法和實戰場景: 一、終極總結表:16大裝飾器全景圖 裝飾器類別V1V2核心作用典型場景Component組件定義??創建標準組件業務UI組件ComponentV2…

【C++】哈希表的實現(unordered_map和unordered_set的底層)

文章目錄 目錄 文章目錄 前言 一、unordered_set和unordered_map介紹 二、哈希表的介紹 三、哈希沖突的解決方法 1.開放定址法 2.鏈地址法 四、兩種哈希表代碼實現 總結 前言 前面我們學習了紅黑樹,紅黑樹就是map和set的底層,本篇文章帶來的是unordered…