Python設計模式:策略模式

1. 什么是策略模式

策略模式(Strategy Pattern)是一種行為型設計模式,它定義了一系列算法,將每個算法封裝起來,并使它們可以互換。策略模式使得算法的變化獨立于使用算法的客戶。換句話說,策略模式允許在運行時選擇算法的實現,從而提高了代碼的靈活性和可維護性。

策略模式通常包含以下幾個角色:

  1. 上下文(Context):持有一個策略的引用,并可以在運行時選擇和切換策略。
  2. 策略接口(Strategy):定義了一個公共接口,用于所有支持的算法。
  3. 具體策略(ConcreteStrategy):實現策略接口的具體算法。
# 策略接口
class PaymentStrategy:def pay(self, amount):pass# 具體策略:信用卡支付
class CreditCardPayment(PaymentStrategy):def pay(self, amount):return f"Processed credit card payment of ${amount}"# 具體策略:PayPal支付
class PayPalPayment(PaymentStrategy):def pay(self, amount):return f"Processed PayPal payment of ${amount}"# 具體策略:支付寶支付
class AlipayPayment(PaymentStrategy):def pay(self, amount):return f"Processed Alipay payment of ${amount}"# 上下文
class PaymentContext:def __init__(self, strategy: PaymentStrategy):self.strategy = strategydef set_strategy(self, strategy: PaymentStrategy):self.strategy = strategydef execute_payment(self, amount):return self.strategy.pay(amount)if __name__ == "__main__":# 創建不同的支付策略credit_card_payment = CreditCardPayment()paypal_payment = PayPalPayment()alipay_payment = AlipayPayment()# 創建上下文并設置策略payment_context = PaymentContext(credit_card_payment)print(payment_context.execute_payment(100))  # 輸出: Processed credit card payment of $100# 切換策略payment_context.set_strategy(paypal_payment)print(payment_context.execute_payment(200))  # 輸出: Processed PayPal payment of $200# 切換策略payment_context.set_strategy(alipay_payment)print(payment_context.execute_payment(150))  # 輸出: Processed Alipay payment of $150
  1. 策略接口(PaymentStrategy):定義了支付的公共接口,所有具體支付策略都實現這個接口。它包含一個 pay 方法,接受支付金額作為參數。

  2. 具體策略(CreditCardPayment、PayPalPayment、AlipayPayment):實現了策略接口的具體支付方式,封裝了各自的支付邏輯。每個具體策略都實現了 pay 方法,提供了不同的支付處理方式。

  3. 上下文(PaymentContext):持有一個策略的引用,并可以在運行時選擇和切換策略。它通過調用策略的 pay 方法來執行支付。上下文可以在運行時更改策略,從而改變支付方式。

感謝您的耐心和反饋!下面是您提供的完整代碼,已經經過整理和確認,確保它能夠正確實現音頻處理的策略模式,包括總 RMS、最大 RMS、最小 RMS、平均 RMS 和峰值幅度的計算,以及音量調整功能。

2. 示例:音頻處理策略模式

import numpy as np
import librosa
import soundfile as sf# 策略接口
class AudioProcessingStrategy:def calculate_rms(self, audio_data, window_size=None):passdef adjust_volume(self, audio_data, target_rms_dbfs, window_size=None):current_rms_dbfs = self.calculate_rms(audio_data, window_size)return self._adjust_volume(audio_data, target_rms_dbfs, current_rms_dbfs, window_size)@staticmethoddef _adjust_volume(audio_data, target_rms_dbfs, current_rms_dbfs, window_size=None):current_rms = 10 ** (current_rms_dbfs / 20)target_rms = 10 ** (target_rms_dbfs / 20)adjustment_factor = target_rms / current_rms if current_rms > 0 else 1.0return audio_data * adjustment_factor# 具體策略:總 RMS
class TotalRMSStrategy(AudioProcessingStrategy):def calculate_rms(self, audio_data, window_size=None):return 20 * np.log10(np.sqrt(np.mean(audio_data ** 2)) + 1.0e-9)# 具體策略:最大 RMS
class MaxRMSStrategy(AudioProcessingStrategy):def calculate_rms(self, audio_data, window_size=None):rms_values = []for start in range(0, len(audio_data), window_size):end = min(start + window_size, len(audio_data))window = audio_data[start:end]if len(window) > 0:rms = 20 * np.log10(np.sqrt(np.mean(window ** 2)) + 1.0e-9)rms_values.append(rms)return np.max(rms_values) if rms_values else -np.inf# 具體策略:最小 RMS
class MinRMSStrategy(AudioProcessingStrategy):def calculate_rms(self, audio_data, window_size=None):rms_values = []for start in range(0, len(audio_data), window_size):end = min(start + window_size, len(audio_data))window = audio_data[start:end]if len(window) > 0:rms = 20 * np.log10(np.sqrt(np.mean(window ** 2)) + 1.0e-9)rms_values.append(rms)return np.min(rms_values) if rms_values else -np.inf# 具體策略:平均 RMS
class AvgRMSStrategy(AudioProcessingStrategy):def calculate_rms(self, audio_data, window_size=None):rms_values = []for start in range(0, len(audio_data), window_size):end = min(start + window_size, len(audio_data))window = audio_data[start:end]if len(window) > 0:rms = 20 * np.log10(np.sqrt(np.mean(window ** 2)) + 1.0e-9)rms_values.append(rms)return np.mean(rms_values) if rms_values else -np.inf# 具體策略:峰值幅度
class PeakAmplitudeStrategy(AudioProcessingStrategy):def calculate_rms(self, audio_data, window_size=None):return 20 * np.log10(np.max(np.abs(audio_data)) + 1.0e-9)# 上下文
# 上下文
class AudioProcessor:def __init__(self, strategy: AudioProcessingStrategy):self.strategy = strategydef set_strategy(self, strategy: AudioProcessingStrategy):self.strategy = strategyreturn self  # 返回自身以支持鏈式調用def calculate_rms(self, audio_data, window_size=None):return self.strategy.calculate_rms(audio_data, window_size)def adjust_volume(self, audio_data, target_rms_dbfs, window_size=None):return self.strategy.adjust_volume(audio_data, target_rms_dbfs, window_size)if __name__ == "__main__":audio_path = './test_volume.wav'audio_data, sr = librosa.load(audio_path, sr=None)# 創建上下文并設置策略audio_processor = AudioProcessor(TotalRMSStrategy())# 計算總 RMS 并調整音量adjusted_audio_total = audio_processor.set_strategy(TotalRMSStrategy()).adjust_volume(audio_data, -20)total_rms = audio_processor.strategy.calculate_rms(audio_data)print(f"Total RMS (dBFS): {total_rms:.2f}")sf.write('./adjusted_audio_total.wav', adjusted_audio_total, sr)# 計算最大 RMS 并調整音量adjusted_audio_max = audio_processor.set_strategy(MaxRMSStrategy()).adjust_volume(audio_data, -20, window_size=1024)max_rms = audio_processor.strategy.calculate_rms(audio_data, window_size=1024)print(f"Max RMS (dBFS): {max_rms:.2f}")sf.write('./adjusted_audio_max.wav', adjusted_audio_max, sr)# 計算最小 RMS 并調整音量adjusted_audio_min = audio_processor.set_strategy(MinRMSStrategy()).adjust_volume(audio_data, -20, window_size=1024)min_rms = audio_processor.strategy.calculate_rms(audio_data, window_size=1024)print(f"Min RMS (dBFS): {min_rms:.2f}")sf.write('./adjusted_audio_min.wav', adjusted_audio_min, sr)# 計算平均 RMS 并調整音量adjusted_audio_avg = audio_processor.set_strategy(AvgRMSStrategy()).adjust_volume(audio_data, -20, window_size=1024)avg_rms = audio_processor.strategy.calculate_rms(audio_data, window_size=1024)print(f"Avg RMS (dBFS): {avg_rms:.2f}")sf.write('./adjusted_audio_avg.wav', adjusted_audio_avg, sr)# 計算峰值幅度并調整音量adjusted_audio_peak = audio_processor.set_strategy(PeakAmplitudeStrategy()).adjust_volume(audio_data, -20)peak_amplitude = audio_processor.strategy.calculate_rms(audio_data)print(f"Peak Amplitude (dBFS): {peak_amplitude:.2f}")sf.write('./adjusted_audio_peak.wav', adjusted_audio_peak, sr)
  1. 策略接口(AudioProcessingStrategy):定義了計算 RMS 和調整音量的公共接口。adjust_volume 方法調用 calculate_rms,并且可以選擇性地傳遞 window_size 參數。

  2. 具體策略

    • TotalRMSStrategy:計算總 RMS 并調整音量。
    • MaxRMSStrategy:計算最大 RMS 并調整音量。
    • MinRMSStrategy:計算最小 RMS 并調整音量。
    • AvgRMSStrategy:計算平均 RMS 并調整音量。
    • PeakAmplitudeStrategy:計算峰值幅度并調整音量。
  3. 上下文(AudioProcessor):持有一個策略的引用,并可以在運行時選擇和切換策略。它通過調用策略的方法來處理音頻數據。

  4. 客戶端代碼:客戶端創建不同的策略,并通過上下文執行音頻處理。客戶端可以在運行時切換策略,靈活應對不同的音頻處理需求。

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

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

相關文章

SpringBoot集成Ollama本地模型

SpringBoot集成Ollama本地模型 目錄 項目準備創建Ollama服務客戶端創建控制器配置應用屬性創建前端界面添加靜態資源支持完整項目結構啟動應用高級功能擴展部署注意事項性能優化 1. 項目準備 創建一個SpringBoot項目,可以使用Spring Initializr或IDE創建添加必要…

ResNet改進(19):基于PyTorch的ResNet改進方案詳解:Mish激活+SPP模塊+MixUp數據增強

1. 前言 ResNet作為深度學習領域里程碑式的網絡架構,在圖像分類等計算機視覺任務中表現出色。然而,隨著研究的深入和技術的發展,原始的ResNet架構仍有改進空間。本文將詳細介紹一種基于PyTorch的ResNet改進方案,該方案融合了Mish激活函數、SPP模塊和MixUp數據增強等先進技…

leetcode68.左右文本對齊

思路源自 leetcode-字符串篇 68題 文本左右對齊 難度高的模擬類型題目,關鍵點在于事先知道有多少單詞要放在本行并且還要知道本行是不是最后一行(最后一行需要全部單空格右對齊,不是最后一行就空格均攤),非最后一行的空…

深入理解 Spring 的 MethodParameter 類

MethodParameter 是 Spring 框架中一個非常重要的類,它封裝了方法參數(或返回類型)的元數據信息。這個類在 Spring MVC、AOP、數據綁定等多個模塊中都有廣泛應用。 核心功能 MethodParameter 主要提供以下功能: 獲取參數類型信息…

Qt 5.14.2入門(一)寫個Hello Qt!程序

目錄 參考鏈接:一、新建項目二、直接運行三、修改代碼增加窗口內容1、Qt 顯示一個 QLabel 標簽控件窗口2、添加按鍵 參考鏈接: Qt5教程(一):Hello World 程序 Qt 編程指南 一、新建項目 1、新建一個項目&#xff08…

Spring Boot 3.x 集成 MongoDB 的 默認配置項及默認值,以及 常用需要修改的配置項 的詳細說明

以下是 Spring Boot 3.x 集成 MongoDB 的 默認配置項及默認值,以及 常用需要修改的配置項 的詳細說明: 一、默認配置項及默認值 Spring Boot 對 MongoDB 的默認配置基于 spring.data.mongodb 前綴,以下是核心配置項: 配置項默認…

【QT】 進程

目錄 QT 多進程復習 Linux-C 多進程QProcess 進程類常用方法簡單示例信號與槽應用場景 跨平臺注意事項技巧:使用宏控制平臺命令 QProcess 在嵌入式系統中的使用示例:調用 ALSA 播放音頻示例:調用 arecord 錄音示例:QProcess Shel…

原子操作(cpp atomic)

目錄 一.原子操作 1.原子操作的概念 2.原子變量 二.原子性 1.中間狀態描述 2.單處理器單核 3.多處理器或多核的情況下 4.cache(高速緩沖器的作用) 5.在cpu cache基礎上,cpu如何讀寫數據??? 6.為什么會有緩存…

Unet網絡的Pytorch實現和matlab實現

文章目錄 一、Unet網絡簡介1.1 輸入圖像1.2 編碼器部分(Contracting Path)1.3 解碼器部分(Expanding Path)1.4 最后一層(輸出)1.5 跳躍連接(Skip Connections) 二、Unet網絡的Pytorc…

記錄一次JVM調優過程1

如何通過jmap 診斷,服務運行一段時間后內存使用量飆升的問題 通過 jmap 診斷服務運行一段時間后內存使用量飆升的問題,需結合堆轉儲分析、對象分布統計及工具鏈配合。以下是具體操作步驟和關鍵方法: 一、實時監控與初步分析 獲取進程 PID 使…

接口自動化學習五:mock工具使用

Moco簡介: Mock是一個簡單搭建模擬服務器的框架,可以用來模擬http、https、socket等協議。 原理: Mock會根據一些配置,啟動一個真正的HTTP服務(會監聽本地的某個端口),當發起的請求滿足某個條件時&#xf…

若依 前后端部署

后端:直接把代碼從gitee上拉去到本地目錄 (https://gitee.com/y_project/RuoYi-Vue ) 注意下redis連接時password改auth 后端啟動成功 前端:運行前首先確保安裝了node環境,隨后執行: !!一定要用管理員權限…

Adaptive AUTOSAR 狀態管理和轉換——ActionItemList

在AUTOSAR的狀態轉換管理(STM,State Transition Manager) 框架中,ActionItemList 是連接 狀態機狀態(State Machine State) 與 功能組狀態(Function Group States) 的核心配置元素。 以下是其關系與作用的詳細解釋: 1. 核心概念 狀態機狀態(State Machine State) 表…

一個基于ragflow的工業文檔智能解析和問答系統

工業復雜文檔解析系統 一個基于ragflow的工業文檔智能解析和問答系統,支持多種文檔格式的解析、知識庫管理和智能問答功能。 系統功能 1. 文檔管理 支持多種格式文檔上傳(PDF、Word、Excel、PPT、圖片等)文檔自動解析和分塊處理實時處理進度顯示文檔解析結果預覽批量文檔…

linux系統下如何提交git和調試

我們默認的ubuntu20.04鏡像是沒有Git提交的工具,我們需要配置安裝包。 安裝和更新git的命令 sudo apt update //用于更新軟件包索引sudo apt install git //用于安裝git版本控制工具 git --version //檢查git版本,確認是否安裝成功 隨便進入linux系統下的一…

輕量級爬蟲框架Feapder入門:快速搭建企業級數據管道

一、目標與前置知識 1. 目標概述 本教程的主要目標是: 介紹輕量級爬蟲框架 Feapder 的基本使用方式。快速搭建一個采集豆瓣電影數據的爬蟲,通過電影名稱查找對應的電影詳情頁并提取相關信息(電影名稱、導演、演員、劇情簡介、評分&#xf…

spring mvc的攔截器HandlerInterceptor 接口詳解

HandlerInterceptor 接口詳解 1. 接口方法說明 方法作用執行時機返回值/注意事項preHandle請求處理前攔截在控制器方法執行前調用返回 false 中斷后續流程;返回 true 繼續執行postHandle控制器方法執行后攔截在控制器方法返回結果后,視圖渲染前調用無返…

數據可視化 —— 柱形圖應用(大全)

一、案例一:單柱形圖 1.導入庫 import matplotlib.pyplot as plt import pandas as pd import numpy as np 2.給窗口名稱和畫布大小 plt.figure(num單柱形圖, figsize(6, 4), facecolorw) 3.定義x、y軸的數據 # range(0-4) x np.arange(5) # 創建數組 y1 np.a…

apijson 快速上手

apijson是強大的工具,簡化了CRUD的操作,只要有數據庫表,就能自動生成RESTFUL接口。但初次上手也是摸索了很長時間,尤其是部署與使用上,這里嘗試以初學者角度來說下: 一、好處 1、對于簡單的應用&#xff…

V4L2雜談

V4L2的開發手冊 在做v4l2的開發的時候, 可以使用v4l2-ctl命令協助調試和軟件開發。關于linux多媒體開發可以參考鏈接:https://www.linuxtv.org/wiki/index.php/Main_Page關于v4l2的api接口開發可以參考:https://linuxtv.org/docs.php在linux…