策略模式入門:基本概念與應用

目錄

  • 策略模式
    • 策略模式結構
    • 策略模式應用場景
    • 策略模式優缺點
    • 練手題目
      • 題目描述
      • 輸入描述
      • 輸出描述
      • 題解

策略模式

策略模式,又稱政策模式,是一種行為型設計模式,它能讓你定義一系列算法,并將每種算法分別放入獨立的類中,以使算法的對象能夠相互替換。

策略模式結構

在這里插入圖片描述

  1. 上下文(Context)維護指向具體策略的引用,且僅通過策略接口與該對象進行交流。
  2. 策略 (Strategy) 接口是所有具體策略的通用接口, 它聲明了一個上下文用于執行策略的方法。
  3. 具體策略 (Concrete Strategies) 實現了上下文所用算法的各種不同變體。
  4. 當上下文需要運行算法時, 它會在其已連接的策略對象上調用執行方法。 上下文不清楚其所涉及的策略類型與算法的執行方式。
  5. 客戶端 (Client) 會創建一個特定策略對象并將其傳遞給上下文。 上下文則會提供一個設置器以便客戶端在運行時替換相關聯的策略。

通用代碼結構示例


//策略接口聲明了某個算法各個不同版本間所共有的操作。
interface Strategy{...
}//具體策略會在遵循策略基礎接口的情況下實現算法。
class ConcreteStrategies implements Strategy{...
}//抽象生成器類
class Context{//抽象策略private Strategy strategy = null;//抽象策略設置具體策略public Context(Strategy s){this.strategy=s;}//封裝具體的方法...}//客戶端
public class Client{Stragety stragety = new ConcrateStrategies();Context context = new Context(Strategy);...
}

策略模式應用場景

  • 當你想使用對象中各種不同的算法變體, 并希望能在運行時切換算法時, 可使用策略模式。

    策略模式讓你能夠將對象關聯至可以不同方式執行特定子任務的不同子對象, 從而以間接方式在運行時更改對象行為。

  • 當你有許多僅在執行某些行為時略有不同的相似類時,可使用策略模式。

    策略模式讓你能將不同行為抽取到一個獨立類層次結構中, 并將原始類組合成同一個, 從而減少重復代碼。

  • 如果算法在上下文的邏輯中不是特別重要, 使用該模式能將類的業務邏輯與其算法實現細節隔離開來。

    策略模式讓你能將各種算法的代碼、 內部數據和依賴關系與其他代碼隔離開來。 不同客戶端可通過一個簡單接口執行算法, 并能在運行時進行切換。

  • 當類中使用了復雜條件運算符以在同一算法的不同變體中切換時,可使用該模式。

    策略模式將所有繼承自同樣接口的算法抽取到獨立類中, 因此不再需要條件語句。 原始對象并不實現所有算法的變體, 而是將執行工作委派給其中的一個獨立算法對象。

在這里插入圖片描述

識別方法:策略模式可以通過允許嵌套對象完成實際工作的方法以及允許將該對象替換為不同對象的設置器來識別。

策略模式優缺點

優點:

  • 你可以在運行時切換對象內的算法。
  • 你可以將算法的實現和使用算法的代碼隔離開來。
  • 你可以使用組合來代替繼承。
  • 開閉原則。 你無需對上下文進行修改就能夠引入新的策略。

缺點:

  • 如果你的算法極少發生改變,那么沒有任何理由引入新的類和接口。使用該模式只會讓程序過于復雜。
  • 客戶端必須知曉策略間的不同——它需要選擇合適的策略。
  • 許多現代編程語言支持函數類型功能, 允許你在一組匿名函數中實現不同版本的算法。 這樣, 你使用這些函數的方式就和使用策略對象時完全相同, 無需借助額外的類和接口來保持代碼簡潔。

練手題目

題目描述

小明家的超市推出了不同的購物優惠策略,你可以根據自己的需求選擇不同的優惠方式。其中,有兩種主要的優惠策略:

  1. 九折優惠策略:原價的90%。
  2. 滿減優惠策略:購物滿一定金額時,可以享受相應的減免優惠。

具體的滿減規則如下:

滿100元減5元

滿150元減15元

滿200元減25元

滿300元減40元

請你設計一個購物優惠系統,用戶輸入商品的原價和選擇的優惠策略編號,系統輸出計算后的價格。

輸入描述

輸入的第一行是一個整數 N(1 ≤ N ≤ 20),表示需要計算優惠的次數。

接下來的 N 行,每行輸入兩個整數,第一個整數M( 0 < M < 400) 表示商品的價格, 第二個整數表示優惠策略,1表示九折優惠策略,2表示滿減優惠策略

輸出描述

每行輸出一個數字,表示優惠后商品的價格

在這里插入圖片描述

題解

1、初次解決思路,簡單的策略模式實現。

import java.util.Scanner;interface Strategy {void preferentialMethod(int price);
}class ConcreteStrategy1 implements Strategy {public void preferentialMethod(int price) {double discountedPrice = 0.9 * price;System.out.println((int) discountedPrice);}
}class ConcreteStrategy2 implements Strategy {public void preferentialMethod(int price) {if (price >= 300) {price = price - 40;} else if (price < 300 && price >=200) {price = price - 25;} else if (price < 200 && price >= 150) {price = price - 15;} else if (price <150 && price >= 100) {price = price - 5;}System.out.println(price);}
}class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void executeStrategy(int price) {strategy.preferentialMethod(price);}
}public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);try {int num = scanner.nextInt();scanner.nextLine(); for (int i = 0; i < num; i++) {String input = scanner.nextLine();String[] parts = input.split(" ");if (parts.length != 2) {System.out.println("輸入錯誤!");break;}int price = Integer.parseInt(parts[0]);int type = Integer.parseInt(parts[1]);Context context = null;switch (type) {case 1:context = new Context(new ConcreteStrategy1());break;case 2:context = new Context(new ConcreteStrategy2());break;default:System.out.println("無效選擇,請輸入1或2");continue;}context.executeStrategy(price);}} catch (Exception e) {System.out.println("An error occurred: " + e.getMessage());} finally {scanner.close();}}
}

2、優化后,使用策略枚舉類實現。

import java.util.Scanner;interface Strategy {void preferentialMethod(int price);
}//策略枚舉類
enum DiscountStrategy implements Strategy {STRATEGY1 {@Overridepublic void preferentialMethod(int price) {double discountedPrice = 0.9 * price;System.out.println((int) discountedPrice);}},STRATEGY2 {@Overridepublic void preferentialMethod(int price) {int[][] discountRules = {{300, 40},{200, 25},{150, 15},{100, 5}};for (int[] rule : discountRules) {if (price >= rule[0]) {price -= rule[1];break;}}System.out.println(price);}};public static DiscountStrategy fromType(int type) {switch (type) {case 1:return STRATEGY1;case 2:return STRATEGY2;default:throw new IllegalArgumentException("無效選擇,請輸入1或2");}}
}class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void executeStrategy(int price) {strategy.preferentialMethod(price);}
}public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);try {int num = scanner.nextInt();scanner.nextLine();for (int i = 0; i < num; i++) {try {String input = scanner.nextLine();String[] parts = input.split(" ");if (parts.length != 2) {System.out.println("輸入錯誤!");continue;}int price = Integer.parseInt(parts[0]);int type = Integer.parseInt(parts[1]);DiscountStrategy strategy = DiscountStrategy.fromType(type);Context context = new Context(strategy);context.executeStrategy(price);} catch (NumberFormatException e) {System.out.println("輸入格式錯誤,請輸入有效的價格和類型!");} catch (IllegalArgumentException e) {System.out.println(e.getMessage());}}} catch (Exception e) {System.out.println("An error occurred: " + e.getMessage());} finally {scanner.close();}}
}

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

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

相關文章

數字研發·驅動變革 | 2024達索系統裝備行業數字化研發專題研討會成功舉辦

2024年6月28日&#xff0c;由百世慧舉辦的“數字研發驅動變革|2024達索系統裝備行業數字化研發專題研討會”在達索系統&#xff08;重慶&#xff09;智能制造創新中心成功舉辦。 隨著全球制造業向著智能化、數字化轉型&#xff0c;我國工業裝備行業也面臨著轉型升級的壓力和機遇…

Gym cuda error: invalid resource handle

gym模擬的時候&#xff0c; 出現問題&#xff1a; sim和gym的定義如下&#xff1a; from isaacgym import gymapi,gymtorch import math,random# 1. Simulation Setup gym gymapi.acquire_gym()# get default set of parameters sim_params gymapi.SimParams() sim_params.u…

網關,路由器,交換機

一、網關 (Gateway) 是一種設備&#xff0c;用于連接不同網絡&#xff0c;能夠轉發數據包并翻譯協議&#xff0c;允許不同類型的網絡通信。網關通常工作在OSI模型的應用層或傳輸層&#xff0c;提供連接和路由服務。 應用場景例子&#xff1a; 在企業網絡中&#xff0c;網關可…

四倍體和六倍體小麥抗赤霉病的比較研究

核心總結&#xff1a;四倍體和六倍體小麥抗赤霉病的比較研究 研究背景 小麥赤霉病&#xff08;Fusarium head blight, FHB&#xff09;由Fusarium graminearum引起&#xff0c;是全球范圍內對小麥生產造成嚴重威脅的疾病。FHB感染不僅會顯著降低糧食產量和質量&#xff0c;還…

2024年能在一個月內錄用的EI檢索會議CCPQT 2024

第三屆計算、通信、感知與量子技術國際會議&#xff08;CCPQT 2024&#xff09;將于2024 年10月25日-10月27日在中國珠海召開。&#xff08;往屆均已順利見刊檢索&#xff09; 會議信息 大會官網&#xff1a;http://www.ccpqt.org/ 會議地點&#xff1a;中國珠海 會議時間&…

企業多存儲方式如何兼顧安全統一管理、便捷流暢訪問的雙向需求?

數據和文件存儲是企業最基礎的需求&#xff0c;常見的存儲方式有磁盤存儲、NAS存儲、SAN存儲、云存儲、分布式存儲、閃存存儲等&#xff1b;隨著企業規模的擴大、業務結構的復雜化&#xff0c;企業內部可能會同時出現多種存儲方式、多個存儲設備并行使用的情況。 這樣的使用場景…

python之音頻處理(1)語速快慢的改變

方案1&#xff1a;使用pydub 處理 from pydub import AudioSegment sound AudioSegment.from_file(r"D:\websiteDownload\我今天被一件事情搞得很煩.wav") print(sound.duration_seconds) rate 0.75 sound_with_altered_frame_rate sound._spawn(sound.raw_data,…

【啟明智顯技術分享】Model3C芯片電阻屏RTP配置、調試與測試指南

一、背景 本指南將詳細介紹啟明智顯的Model3C芯片電阻屏RTP配置、調試與測試指南。無論您是電子愛好者、開發者還是工程師&#xff0c;這份指南都能助您快速上手并充分利用這款觸摸屏的各項功能。 二、芯片介紹 Model3C是一款基于RISC-V的高性能、國產自主、工業級高清顯示與…

java通過jts獲取點在線段中的位置

在Java中&#xff0c;可以使用JTS&#xff08;Java Topology Suite&#xff09;庫來獲取點在線段的垂足點位置。以下是一個簡單的示例代碼&#xff0c;展示了如何使用JTS獲取點到線段的垂足點位置&#xff1a; 首先&#xff0c;確保你的項目中包含了JTS庫。 import org.locati…

面試篇-系統設計題總結

這里記錄一些有趣的系統設計類的題目&#xff0c;一般大家比較喜歡出的設計類面試題目會和高可用系統相關比如秒殺和搶紅包等。歡迎大家在評論中評論自己遇到的題目&#xff0c;本篇文章會持續更新。 1、設計一個搶紅包系統 搶紅包系統其實也是秒殺類中的一個場景&#xff0…

深度學習中的反向傳播算法的原理

深度學習中的反向傳播算法的原理&#xff0c;以及如何計算梯度 反向傳播算法&#xff08;Backpropagation&#xff09;是深度學習中最核心的優化技術之一&#xff0c;用于訓練神經網絡。它基于鏈式法則&#xff0c;通過從輸出層逆向計算誤差并逐層傳遞到輸入層來更新模型參數&…

類的動態加載-雙親委派模型

java反射基礎 Java 基礎 - 反射機制詳解 | Java 全棧知識體系 (pdai.tech) 類的動態加載 參考鏈接&#xff1a;類的動態加載 構造是和實例化也就是對象相關的。 靜態代碼塊是在初始化的時候就調用的 Class.forName();就會調用靜態代碼塊 forName&#xff0c;加載類時默認…

你們叫AI,我們叫DI

大家好&#xff0c;才是真的好。 最近Notes/Domino產品在做哪些更新&#xff0c;想必大家都很好奇。 從2022年年末到現在&#xff0c;快兩年了&#xff0c;任何一個有追求的大企業或巨頭&#xff0c;應該都在追求實現一件事情&#xff1a;AI人工智能。 從小道消息來看&#…

深度學習之OpenCV的DNN模塊

OpenCV的DNN&#xff08;Deep Neural Network&#xff09;模塊是一個強大的工具&#xff0c;允許開發者在計算機視覺應用中使用深度學習模型。該模塊支持多種深度學習框架和模型格式&#xff0c;并提供了高效的推理能力。以下是對OpenCV DNN模塊的詳細介紹&#xff0c;包括其功…

Unity實現等弧長的曲線滾動列表

Unity實現等弧長的曲線滾動列表 在Unity中實現等弧長的曲線滾動列表通常涉及到曲線路徑生成、物理模擬以及動畫控制。首先&#xff0c;你需要創建一個可滾動的UI元素&#xff08;如List或ScrollView&#xff09;&#xff0c;并將其錨點設置在一個可以跟隨曲線移動的位置。以下…

掃描工具Metasploit的安裝和使用

安裝 Metasploit 你可以使用 Metasploit 的安裝腳本從 Rapid7 官方站點下載安裝。 更新系統包&#xff1a; sudo apt update下載并安裝 Metasploit&#xff1a; curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framew…

【高級篇】分區與分片:MySQL的高級數據管理技術(十三)

引言 在上一章,我們探討了MySQL的主從復制與高可用性,這是構建健壯數據庫架構的基石。現在,讓我們深入到更高級的主題——分區與分片,這些技術對于處理大規模數據集和提升數據庫性能至關重要。我們將詳細介紹表分區的概念、類型及分片技術的應用,為下一章討論MySQL集群與…

小程序怎么跳轉到其他小程序里

小程序跳轉到其他小程序里&#xff0c;可以通過微信小程序提供的API實現。以下是幾種常見的跳轉方式&#xff0c;以及相應的實現方法&#xff1a; 1. 直接跳轉 使用API&#xff1a; wx.navigateToMiniProgram 參數說明&#xff1a; appId&#xff08;string類型&#xff0c…

Idea2024安裝后點擊無響應

問題 最近因工作需要&#xff0c;升級一下 idea 版本&#xff0c;之前一直使用的是2020版本&#xff0c;下載最新的2024版本&#xff08;下載的 zip 包免安裝模式&#xff0c;之前使用的2020版本也是免安裝的&#xff0c;因為是免安裝的&#xff0c;所以之前的版本也沒有刪除&…

解決Vue3中路由頁面跳轉出現白屏,刷新頁面之后展示正常的問題

遇到這個問題&#xff0c;首先需要檢查根組件標簽最外層是否包含了個最大的div盒子來包裹內容。如下圖所示&#xff1a; 我的項目就是因為沒有將兩塊內容放到一個大盒子里面&#xff0c;所以才會出現白屏的問題。然后我去查了相關的資料&#xff0c;了解到這個問題是Vue組件渲染…