設計模式基礎概念(行為模式):策略模式

概述

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

主要目的是通過定義相似的算法,替換if else 語句寫法,并且可以隨時相互替換

結構

在這里插入圖片描述

示例

策略模式在 Java 代碼中很常見。 它經常在各種框架中使用, 能在不擴展類的情況下向用戶提供改變其行為的方式。

javax.servlet.http.HttpServlet: ? service-()方法, 還有所有接受 Http-Servlet-Request和 Http-Servlet-Response對象作為參數的 do-XXX()方法。

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

偽代碼實現

strategies

策略(strategies)的定義:所有具體策略的通用接口, 它聲明了一個上下文用于執行策略的方法

public interface PayStrategy {boolean pay(int paymentAmount);void collectPaymentDetails();
}

Concrete Strategies

具體策略 (Concrete Strategies): 實現上下文所用算法的各種不同變體。

PayByPayPal: 使用 PayPal 支付

public class PayByPayPal implements PayStrategy {@Overridepublic void collectPaymentDetails() {// todo}@Overridepublic boolean pay(int paymentAmount) {// todo}

PayByCreditCard: 使用信用卡支付

public class PayByCreditCard implements PayStrategy {@Overridepublic void collectPaymentDetails() {// todo}@Overridepublic boolean pay(int paymentAmount) {// todo}

Context

上下文 (Context): 維護指向具體策略的引用, 且僅通過策略接口與該對象進行交流。

public class Order {private int totalCost = 0;private boolean isClosed = false;// 提供一個計算的接口供客戶端使用。public void processOrder(PayStrategy strategy) {strategy.collectPaymentDetails();// Here we could collect and store payment data from the strategy.}}

Client

客戶端 (Client) 會創建一個特定策略對象并將其傳遞給上下文。

上下文則會提供一個設置器以便客戶端在運行時替換相關聯的策略。

public class Client {private static Map<Integer, Integer> priceOnProducts = new HashMap<>();private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));private static Order order = new Order();private static PayStrategy strategy;static {priceOnProducts.put(1, 2200);priceOnProducts.put(2, 1850);priceOnProducts.put(3, 1100);priceOnProducts.put(4, 890);}public static void main(String[] args) throws IOException {while (!order.isClosed()) {int cost;String continueChoice;do {System.out.print("Please, select a product:" + "\n" +"1 - Mother board" + "\n" +"2 - CPU" + "\n" +"3 - HDD" + "\n" +"4 - Memory" + "\n");int choice = Integer.parseInt(reader.readLine());cost = priceOnProducts.get(choice);System.out.print("Count: ");int count = Integer.parseInt(reader.readLine());order.setTotalCost(cost * count);System.out.print("Do you wish to continue selecting products? Y/N: ");continueChoice = reader.readLine();} while (continueChoice.equalsIgnoreCase("Y"));if (strategy == null) {System.out.println("Please, select a payment method:" + "\n" +"1 - PalPay" + "\n" +"2 - Credit Card");String paymentMethod = reader.readLine();// Client creates different strategies based on input from user,// application configuration, etc.if (paymentMethod.equals("1")) {strategy = new PayByPayPal();} else {strategy = new PayByCreditCard();}}// Order object delegates gathering payment data to strategy object,// since only strategies know what data they need to process a// payment.order.processOrder(strategy);System.out.print("Pay " + order.getTotalCost() + " units or Continue shopping? P/C: ");String proceed = reader.readLine();if (proceed.equalsIgnoreCase("P")) {// Finally, strategy handles the payment.if (strategy.pay(order.getTotalCost())) {System.out.println("Payment has been successful.");} else {System.out.println("FAIL! Please, check your data.");}order.setClosed();}}}
}

應用場景

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

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

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

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

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

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

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

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

實現步驟

首先,從上下文類中找出修改頻率較高的算法

其次,聲明該算法所有變體的通用策略接口。將算法逐一抽取到各自的類中, 它們都必須實現策略接口。

之后,在上下文類中添加一個成員變量用于保存對于策略對象的引用

  • 然后提供設置器以修改該成員變量。
  • 上下文僅可通過策略接口同策略對象進行交互,
  • 如有需要還可定義一個接口來讓策略訪問其數據。

最后,客戶端必須將上下文類與相應策略進行關聯, 使上下文可以預期的方式完成其主要工作。

優缺點

策略模式優點:

  • 擴展性好,可以在不修改對象結構的情況下,為新的算法進行添加新的類進行實現;
  • 靈活性好,可以對算法進行自由切換;

策略模式缺點:

  • 使用策略類變多,會增加系統的復雜度。;
  • 客戶端必須知道所有的策略類才能進行調用;

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

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

相關文章

功能組和功能組狀態的概念關系和區別

在 AUTOSAR Adaptive Platform 中&#xff0c;功能組&#xff08;Function Group&#xff0c;FG&#xff09; 和 功能組狀態&#xff08;Function Group State&#xff09; 是狀態管理&#xff08;SM&#xff09;的核心概念&#xff0c;二者構成靜態邏輯單元與動態行為模式的協…

力扣326:3的冪

力扣326:3的冪題目思路代碼題目 給定一個整數&#xff0c;寫一個函數來判斷它是否是 3 的冪次方。如果是&#xff0c;返回 true &#xff1b;否則&#xff0c;返回 false 。 整數 n 是 3 的冪次方需滿足&#xff1a;存在整數 x 使得 n 3^x 思路 想要是三的冪次方的話將這個…

前瞻性技術驅動,楓清科技助力制造企業借助大模型完成生產力轉化

麥肯錫于近期發布的《技術趨勢展望2025》更清晰地定義了AI的角色與發展方向。報告在不止一個章節總結了基礎模型加速小型化的趨勢&#xff0c;多模態融合成為主流&#xff1a;企業的模型利用從追求“大而全”轉向“小而精”&#xff0c;高效專用小模型成本降低90%的同時保持性能…

如何遠程連接云服務器上mysql

一&#xff1a;使用系統命令查看端口占用# 查看MySQL進程及其端口sudo netstat -tlnp | grep mysql# 或者使用ss命令sudo ss -tlnp | grep mysql# 查看3306端口&#xff08;MySQL默認端口&#xff09;sudo netstat -tlnp | grep 3306出現如下信息&#xff0c;說明端口3306[root…

今日分享:C++模板(全詳解)

&#x1f60e;【博客主頁&#xff1a;你最愛的小傻瓜】&#x1f60e; &#x1f914;【本文內容&#xff1a;C模板 &#x1f60d; 】&#x1f914; -------------------------------------------------------------------------------------------------------------------…

ramdisk內存虛擬盤(一)——前世今生

1990 年代&#xff1a;前因——“硬盤太慢、驅動太多” 背景&#xff1a;早期 Linux 根文件系統要么在軟盤、要么在 IDE 硬盤&#xff0c;內核把對應的軟盤/IDE 驅動編進去即可順利掛載。矛盾出現&#xff1a;隨著 SCSI、PCMCIA、USB、RAID 控制器等百花齊放&#xff0c;如果把…

ETH持續上漲推動DEX熱潮,交易活躍度飆升的XBIT表現強勢出圈

BOSS Wallet 8月15日訊&#xff0c;隨著ETH價格在過去24小時內強勢拉升至4300美元&#xff0c;整個加密市場再度掀起漲勢狂潮&#xff0c;鏈上交易活躍度空前高漲。其中&#xff0c;去中心化交易所平臺迅速成為市場焦點&#xff0c;其平臺活躍度與交易量雙雙上漲&#xff0c;吸…

Stand-In - 輕量級人物一致性視頻生成 高保真視頻人臉交換 ComfyUI工作流 支持50系顯卡 一鍵整合包下載

Stand-In 是一個輕量級、即插即用的身份保護視頻生成框架&#xff0c;只需要上傳一張人物照片&#xff0c;加上一段提示詞&#xff0c;即可生成高度一致性的高保真人物視頻&#xff0c;人臉相似度和自然都幾乎達到100%還原水平。 Stand-In 能把任何一張人臉&#xff08;甚至動漫…

vue3相關基礎

1、ref和reactive的區別兩者都是響應式數據的聲明。Reactive只適用于非基本數據類型&#xff0c;如對象&#xff0c;數組等。而ref是兼容適用于reactive的的數據類型的以及其他數據&#xff0c;靈活性較高。ref聲明的變量取值時需要.value。在<template></template>…

云手機存儲和本地存儲的區別

云手機存儲通常指云存儲&#xff0c;即數據存儲在云端服務器&#xff0c;本地存儲則是將數據存儲在用戶設備硬件中&#xff0c;主要區別體現在存儲位置、訪問方式、依賴條件等多個方面&#xff0c;具體如下&#xff1a;本地存儲主要是將數據存儲在用戶自有設備的物理硬件中&…

【科研繪圖系列】R語言繪制三維曲線圖

文章目錄 介紹 加載R包 數據下載 導入數據 數據預處理 畫圖 系統信息 參考 介紹 【科研繪圖系列】R語言繪制三維曲線圖 加載R包 library(tidyverse) library(ggsignif) library(RColorBrewer) library(dplyr) library(reshape2) library(grid

python常用包

以下按類別列舉10個常用Python包&#xff0c;并以一句話概括其核心作用&#xff1a; 一、數據分析與科學計算 NumPy&#xff1a;提供高性能多維數組及數學運算&#xff0c;是數值計算的基礎庫。Pandas&#xff1a;通過DataFrame結構實現高效表格數據清洗、分析與處理。SciPy&am…

“ 船新版本 ”

在 GeeLark 最新版本中&#xff0c;增強了 AIGC 生成能力以及 AI 協助自定義任務開發功能&#xff0c;給用戶優化構建從內容生產到運營自動化的完整技術鏈&#xff0c;為跨境電商及企業用戶提供更完善的智能化解決方案&#xff0c;效率翻倍輕松出海。 AIGC 接入 MiniMax-Hailuo…

力扣 —— 二分查找

搜索插入位置 35. 搜索插入位置 - 力扣&#xff08;LeetCode&#xff09; 算法思想&#xff1a; class Solution(object):def searchInsert(self, nums, target):left0 rightlen(nums)-1while left < right :mid (left right) // 2if nums[mid] < target:left mid 1…

USB ADB 簡介

概念 ADB 是 Android 平臺的 調試橋接協議&#xff0c;允許主機&#xff08;PC&#xff09;與 Android 設備通信。 通過 ADB&#xff0c;開發者可以執行命令、調試應用、傳輸文件、訪問 shell、調試 logcat 等。 ADB 運行在 USB 或 TCP/IP 上&#xff0c;但最常用的是 USB 連…

【Golang】:數據類型

目錄 1. 基本數據類型 1.1 布爾類型 1.2 整數類型 1.3 浮點數類型 1.4 復數類型 1.5 字符類型 1.6 字符串類型 2. 類型轉換 2.1 基本數據類型 → string 2.2 string → 基本數據類型 3. 常量 1. 基本數據類型 1.1 布爾類型 Go中的布爾類型取值為true或false&#…

旋鈕鍵盤項目---foc講解(開環)

這里就不過多的講解什么原理&#xff0c;公式的變換了&#xff0c;感興趣的可以看燈哥開源&#xff0c;講解的非常好的。當然&#xff0c;更細致的講解&#xff0c;也可以看b站其他教學。 我這里主要講解我對于開環部分的理解&#xff0c;以及stm32代碼的實現邏輯。可以看作是…

數據科學與計算:爬蟲和數據分析案例筆記

案例 1&#xff1a;中國大學排名爬取與分析 一、任務描述 目標&#xff1a;爬取高三網中國大學排名一覽表&#xff0c;提取學校名稱、總分、全國排名、星級排名、辦學層級等數據&#xff0c;并保存為 CSV 文件。 網址&#xff1a;2021中國的大學排名一覽表_高三網 二、任務…

華測科技的3D GPR數據分析

很高興得到了張總的支持&#xff0c;獲得了他們雷達的數據&#xff0c;并寫了雷達數據讀取和轉換文件。1 背景搜索后發現華測實力很強&#xff0c;因為他們可達到100km/h的時速&#xff0c;以前我只知道中電眾益可以達到這個速度。2數據格式分析2.1 華測數據因為長時間不編程&a…

最長鏈(二叉樹直徑DFS)

題目描述現給出一棵N個結點二叉樹&#xff0c;問這棵二叉樹中最長鏈的長度為多少&#xff0c;保證了1號結點為二叉樹的根。輸入第1行為包含了一個正整數N&#xff0c;為這棵二叉樹的結點數&#xff0c;結點標號由1至N。 接下來N行&#xff0c;這N行中的第i行包含兩個正整數l[i]…