Python设计模式:策略模式
1. 什么是策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式使得算法的变化独立于使用算法的客户。换句话说,策略模式允许在运行时选择算法的实现,从而提高了代码的灵活性和可维护性。
策略模式通常包含以下几个角色:
- 上下文(Context):持有一个策略的引用,并可以在运行时选择和切换策略。
- 策略接口(Strategy):定义了一个公共接口,用于所有支持的算法。
- 具体策略(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
-
策略接口(PaymentStrategy):定义了支付的公共接口,所有具体支付策略都实现这个接口。它包含一个
pay方法,接受支付金额作为参数。 -
具体策略(CreditCardPayment、PayPalPayment、AlipayPayment):实现了策略接口的具体支付方式,封装了各自的支付逻辑。每个具体策略都实现了
pay方法,提供了不同的支付处理方式。 -
上下文(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)
-
策略接口(AudioProcessingStrategy):定义了计算 RMS 和调整音量的公共接口。
adjust_volume方法调用calculate_rms,并且可以选择性地传递window_size参数。 -
具体策略:
- TotalRMSStrategy:计算总 RMS 并调整音量。
- MaxRMSStrategy:计算最大 RMS 并调整音量。
- MinRMSStrategy:计算最小 RMS 并调整音量。
- AvgRMSStrategy:计算平均 RMS 并调整音量。
- PeakAmplitudeStrategy:计算峰值幅度并调整音量。
-
上下文(AudioProcessor):持有一个策略的引用,并可以在运行时选择和切换策略。它通过调用策略的方法来处理音频数据。
-
客户端代码:客户端创建不同的策略,并通过上下文执行音频处理。客户端可以在运行时切换策略,灵活应对不同的音频处理需求。
相关文章:
Python设计模式:策略模式
1. 什么是策略模式 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式使得算法的变化独立于使用算法的客户。换句话说,策略模式允许在运…...
JavaScript(JS进阶)
目录 00闭包 01函数进阶 02解构赋值 03通过forEach方法遍历数组 04深入对象 05内置构造函数 06原型 00闭包 <!-- 闭包 --><html><body><script>// 定义:闭包内层函数(匿名函数)外层函数的变量(s&…...
C/C++共有的类型转换与c++特有的四种强制类型转换
前言 C 语言和 C 共有的类型转换: 自动类型转换(隐式类型转换): 编译器在某些情况下会自动进行的类型转换。强制类型转换(显示类型转换): 使用 (type)expression 或 type(expression) 语法进行…...
Nginx 负载均衡案例配置
负载均衡案例 基于 docker 进行 案例测试 1、创建三个 Nginx 实例 创建目录结构 为每个 Nginx 实例创建单独的目录,用于存储 HTML 文件和配置文件 mkdir -p data/nginx1/html mkdir -p data/nginx2/html mkdir -p data/nginx3/html添加自定义 HTML 文件 在每个…...
【蓝桥杯】贪心算法
1. 区间调度 1.1. 题目 给定个区间,每个区间由开始时间start和结束时间end表示。请选择最多的互不重叠的区间,返回可以选择的区间的最大数量。 输入格式: 第一行包含一个整数n,表示区间的数量 接下来n行,每行包含两个整数,分别表示区间的开始时间和结束时间 输出格式:…...
LLaMA-Factory 数据集成从入门到精通
一、框架概述 LLaMA-Factory 框架通过Alpaca/Sharegpt双格式体系实现多任务适配,其中Alpaca专注结构化指令微调(含SFT/DPO/预训练),Sharegpt支持多角色对话及多模态数据集成。核心配置依托 dataset_info.json 实现数据源映射、格…...
数据库架构
常见数据库架构类型及其优势解析 1. 集中式架构(Centralized Architecture) 定义:所有数据存储在单个服务器或主机上,由中央处理器统一管理。核心优势: ✅ 数据一致性:单一数据源避免数据冗余和不一致。 …...
OSPF接口的网络类型和不规则区域
网络类型(数据链路层所使用的协议所构建的二层网络类型) 1、MA --- 多点接入网络 BMA --- 支持广播的多点接入网络 NBMA --- 不支持广播的多点接入网络 2、P2P --- 点到点网络 以太网 --- 以太网最主要的特点是需要基于MAC地址进行物理寻址,主要是因为以太网接口所连…...
MySQL SQL Mode
SQL Mode 是 MySQL 中一个重要的系统变量,它决定了 MySQL 应遵循的 SQL 语法规则和数据验证规则。 什么是 SQL Mode SQL Mode 定义了 MySQL 应该支持的 SQL 语法以及执行数据验证的方式。通过设置不同的 SQL Mode,可以让 MySQL 在不同程度上兼容其他数据…...
Mysql备忘记录
1、简介 Mysql操作经常忘记命令,本文将持续记录Mysql一些常用操作。 2、常见问题 2.1、忘记密码 # 1、首先停止Mysql服务 systemctl stop mysqld # windows 从任务管理器里面停 # 2、更改配置文件 my.cnf (windows是 ini文件) vim /etc/my.cnf 在[mysqld]下面添…...
idea 创建 maven-scala项目
文章目录 idea 创建 maven-scala项目1、创建普通maven项目并且配置pom.xml文件2、修改项目结构1)创建scala目录并标记成【源目录】2)导入scala环境3)测试环境 idea 创建 maven-scala项目 1、创建普通maven项目并且配置pom.xml文件 maven依赖…...
ansible+docker+docker-compose快速部署4节点高可用minio集群
目录 github项目地址 示例服务器列表 安装前 修改变量文件group_vars/all.yml 修改ansible主机清单 修改setup.sh安装脚本 用法演示 安装后验证 github项目地址 https://github.com/sulibao/ansible_minio_cluster.git 示例服务器列表 安装前 修改变量文件group_var…...
使用libcurl编写爬虫程序指南
用户想知道用Curl库编写的爬虫程序是什么样的。首先,我需要明确Curl本身是一个命令行工具和库,用于传输数据,支持多种协议。而用户提到的“Curl库”可能指的是libcurl,这是一个客户端URL传输库,可以用在C、C等编程语言…...
K8S学习之基础七十五:istio实现灰度发布
istio实现灰度发布 上传镜像到harbor 创建两个版本的pod vi deployment-v1.yaml apiVersion: apps/v1 kind: Deployment metadata:name: appv1labels:app: v1 spec:replicas: 1selector:matchLabels:app: v1apply: canarytemplate:metadata:labels:app: v1apply: canaryspec…...
【设备连接涂鸦阿里云】
设备连接涂鸦阿里云 ■ Tuya IoT on Alibaba Cloud■ 控制台操作步骤■ 1. 创建产品■ 2. 添加设备■ 3. 添加设备■ 4. 获取设备MQTT连接参数 ■ MQTTX使用教程■ 1,先在 Tuya IoT on Alibaba Cloud 新建产品和设备■ 2,MQTTX 设置■ 3,MQTT…...
c语言学习16——内存函数
内存函数 一、memcpy使用和模拟实现1.1参数1.2 使用1.3 模拟实现 二、memmove使用和模拟实现2.1 参数2.2 使用2.3 模拟实现 三、memset使用3.1 参数3.2 使用 四、memcmp使用4.1 参数4.2 使用 一、memcpy使用和模拟实现 1.1参数 因为内存中不知道存的是什么类型的地址ÿ…...
渗透测试实战:使用Hydra破解MySQL弱口令(附合法授权流程+防御方案)
渗透测试实战:使用Hydra破解MySQL弱口令(附合法授权流程防御方案) 郑重声明:本文仅供安全学习研究,任何未经授权的网络攻击行为均属违法。实操需获得目标系统书面授权,请遵守《网络安全法》相关规定。 一、…...
一文了解亿级数据检索:RedisSearch
文章目录 1.什么是Redis Search2.为什么要使用Redis Search3.RedisSearch 的核心特性4.RedisSearch 的原理4.1 倒排索引4.2 索引创建与数据存储4.3 数据模型4.4 搜索查询处理4.5 高性能与可扩展性: 5.有了ES为什么还需要RedisSearch5.RedisSearch的安装6.RedisSearc…...
uniApp开发微信小程序-连接蓝牙连接打印机上岸!
历经波折三次成功上岸! 三次经历简单絮叨一下:使用uniAppvue开发的微信小程序,使用蓝牙连接打印机,蓝牙所有的接口都是插件中封装的,用的插件市场中的这个: dothan-lpapi-ble ;所以,…...
Spring Boot 线程池配置详解
Spring Boot 线程池配置详解 一、核心配置参数及作用 基础参数核心线程数 (corePoolSize) 作用:线程池中始终保持存活的线程数量,即使空闲也不回收。 建议:根据任务类型设定(如 I/O 密集型任务可设为 CPU 核心数 2)。 最大线程数 (maxPoolSize) 作用:…...
【特权FPGA】之按键消抖
完整代码如下所示: timescale 1ns / 1ps// Company: // Engineer: 特权 // // Create Date: // Design Name: // Module Name: // Project Name: // Target Device: // Tool versions: // Description: // // Dependencies: // // Revision: // …...
P1331 洛谷 海战
题目描述 思路 这个题需要读懂题意,即“什么样的形式表示两只船相撞?” ----> 上下相邻或左右相邻 如果图是不和法的,一定存在如下结构: # # . # 或 # # # . 或 # . # # 或 . # # #即四个格子里有三个#,一个"…...
Python 实现的运筹优化系统数学建模详解(最大最小化模型)
一、引言 在数学建模的实际应用里,最大最小化模型是一种极为关键的优化模型。它的核心目标是找出一组决策变量,让多个目标函数值里的最大值尽可能小。该模型在诸多领域,如资源分配、选址规划等,都有广泛的应用。本文将深入剖析最大…...
网络安全·第二天·ARP协议安全分析
今天我们来考虑考虑计算机网络中的一类很重要的协议-------ARP协议,介绍他用途的同时,分析分析ARP协议存在的一些漏洞及其相关的协议问题。 一、物理地址与IP地址 1、举例 在计算机网络中,有两类地址十分关键,一类称为物理地址&a…...
Python设计模式:命令模式
1. 什么是命令模式? 命令模式是一种行为设计模式,它将请求封装为一个对象,从而使您能够使用不同的请求、队列或日志请求,以及支持可撤销操作。 命令模式的核心思想是将请求的发送者与请求的接收者解耦,使得两者之间的…...
华为手机或平板与电脑实现文件共享
1.手机或平板与电脑在同一个网络 2.打开手机或平板端,设置---更多连接----快分享或华为分享打开此功能-----开启共享至电脑 3.打开电脑,网络中就可看到手机端分享的用户名称 4. 登陆就可访问手机 5.常见问题 5.1 电脑未发现本机 5.2 修改了访问密码后再…...
幻兽帕鲁(Palworld)在线工具集:让游戏体验更轻松!
幻兽帕鲁(Palworld)在线工具集:让游戏体验更轻松! 🎮 工具介绍 为了帮助广大幻兽帕鲁玩家更好地享受游戏,我开发了这个全面的在线工具集。无需下载安装,打开网页即可使用,完全免费! …...
学习51单片机Day02---实验:点亮一个LED灯
目录 1.先看原理图 2.思考一下(sbit的使用): 3.给0是要让这个LED亮(LED端口设置为低电平) 4.完成的代码 1.先看原理图 比如我们要让LED3亮起来,对应的是P2^2。 2.思考一下(sbit的使用&…...
【Kubernetes】Kubernetes 如何进行日志管理?Fluentd / Loki / ELK 适用于什么场景?
由于 Kubernetes 运行在容器化的环境中,应用程序和系统日志通常分布在多个容器和节点上,传统的日志管理方法(例如直接访问每个节点的日志文件)在 Kubernetes 中不适用。 因此,Kubernetes 引入了集中式日志管理方案&am…...
如何使用通义灵码学习JavaScript和DOM
如果你看到了本手册的页面数量,你就会发现JavaScript的API真的非常丰富,在MDN上专门有一大分类用于介绍JavaScript的API,但软件工程行业有一个著名法则叫2-8法则,意思是只有20%的内容会经常使用到,而80%的内容只在一些…...
