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.mzph.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…