当前位置: 首页 > article >正文

设计模式 Day 8:策略模式(Strategy Pattern)完整讲解与实战应用


🔄 前情回顾:Day 7 重点回顾

在 Day 7 中,我们彻底讲透了观察者模式:

它是典型的行为型模式,核心理念是“一变多知”,当一个对象状态变化时,自动通知所有订阅者。

我们通过 RxCpp 实现了工业级的事件广播系统,实现了多个模块订阅同一个数据源。

实战中,如协议解包系统、GUI 事件响应、股票系统等,都广泛采用观察者机制。

🔁 观察者模式强调“自动推送消息”,而今天我们进入策略模式,它更强调“主动选择行为”!



在这里插入图片描述

策略模式(Strategy Pattern)是行为型设计模式中最具“切换能力”的一个,它的设计哲学非常明确:

将算法(行为)抽象为可替换的策略,使得行为的改变不依赖于使用它的对象本身。

策略模式特别适合处理:

  • 多种业务逻辑切换(如支付方式)
  • 动态选择不同算法(如压缩、路径规划)
  • 可扩展、可配置的“策略中心”

本篇 Day 8,将从“动机、结构、语法、实战场景、项目代码、面试回答”六大维度,构建你对策略模式的完整掌握。


一、设计动机:为什么要用策略模式?

✅ 需求背景举例:

  • 一个支付接口,支持支付宝、微信、银行卡……你会怎么设计?
  • 一个路径规划功能,支持最短路、最便宜路径、最快路径……如何实现动态切换?

如果使用 if-else 分支写法:

if (type == "alipay") {...
} else if (type == "wechat") {...
}

✅ 缺点:

  • 不符合开闭原则
  • 不方便扩展新策略
  • 无法复用策略逻辑

这时就需要策略模式!


二、结构定义与核心要点

✅ UML 类图结构

+------------------+
|   Strategy       |<------------------------------+
+------------------+                               |
| + execute()      |                               |
+------------------+                               |/\                                          |||                                          |
+-------------------+     +-----------------------+ |
| AlipayStrategy     |     | WeChatStrategy        | |
+-------------------+     +-----------------------+ |
| + execute()        |     | + execute()           | |
+-------------------+     +-----------------------+ ||+------------------------------+     ||     PaymentContext           |-----++------------------------------+| - strategy: Strategy*        || + setStrategy(Strategy*)     || + pay()                      |+------------------------------+

✅ 角色说明

角色职责
Strategy策略接口,声明统一算法方法
ConcreteStrategy具体策略类,封装各自逻辑
Context上下文,持有当前策略对象

三、完整 C++ 实现

✅ 抽象策略接口

class PaymentStrategy {
public:virtual void pay(int amount) = 0;virtual ~PaymentStrategy() = default;
};

✅ 具体策略类

class AlipayStrategy : public PaymentStrategy {
public:void pay(int amount) override {std::cout << "使用支付宝支付: " << amount << " 元" << std::endl;}
};class WeChatStrategy : public PaymentStrategy {
public:void pay(int amount) override {std::cout << "使用微信支付: " << amount << " 元" << std::endl;}
};class CreditCardStrategy : public PaymentStrategy {
public:void pay(int amount) override {std::cout << "使用信用卡支付: " << amount << " 元" << std::endl;}
};

✅ 上下文类

class PaymentContext {
private:std::unique_ptr<PaymentStrategy> strategy_;public:void setStrategy(std::unique_ptr<PaymentStrategy> strategy) {strategy_ = std::move(strategy);}void pay(int amount) {if (strategy_)strategy_->pay(amount);elsestd::cout << "未设置支付方式!" << std::endl;}
};

✅ 使用示例

int main() {PaymentContext context;context.setStrategy(std::make_unique<AlipayStrategy>());context.pay(100);context.setStrategy(std::make_unique<WeChatStrategy>());context.pay(200);context.setStrategy(std::make_unique<CreditCardStrategy>());context.pay(300);return 0;
}

四、真实项目中策略模式的应用场景

应用领域策略角色示例
支付系统支付方式切换:微信、支付宝、银行卡
压缩服务gzip、zip、lz4 等算法策略
游戏角色AI攻击策略、防御策略、逃跑策略
电商促销系统折扣策略、满减策略、积分兑换策略
导航/路径规划最快路线、最短路线、避开拥堵路线
编解码框架JSON、XML、YAML 策略
图像处理多种滤镜、降噪算法策略

五、与状态模式、策略模式、工厂模式的对比

对比项策略模式状态模式工厂模式
意图封装行为算法,动态切换封装对象状态与行为封装创建过程,替代 new
变化点行为逻辑状态 + 行为对象类型
是否持有引用Context 中持有策略对象状态机中持有当前状态对象工厂方法中返回具体对象

六、面试表达模板 + 问答技巧

❓面试官:你用过策略模式吗?什么场景?

✅ 回答示例:

“在我们支付平台中使用了策略模式来解耦支付方式。我们定义了 PaymentStrategy 接口,具体实现了 AlipayStrategyWeChatStrategy 等类,业务调用通过 PaymentContext 设置策略并执行。策略模式让新增支付方式变得非常方便,无需改动旧逻辑,只需新增类即可。”

✅ 加分点:

  • 强调“符合开闭原则”
  • 使用 std::unique_ptr 管理生命周期
  • 提出策略配置可从配置文件加载(JSON -> 类)

七、总结回顾 + 记忆口诀

✅ 策略模式关键词:

  • 行为可切换
  • 算法封装
  • 运行时替换
  • 开闭原则
  • 模块解耦

📌 记忆口诀:

“行为封装进策略,替换逻辑不靠 if,扩展功能加新类,变化收敛更灵活。”


八、明日预告:Day 9

命令模式(Command Pattern)实战详解:解耦请求者与执行者,构建可撤销、可重做、可排队的操作系统。

相关文章:

设计模式 Day 8:策略模式(Strategy Pattern)完整讲解与实战应用

&#x1f504; 前情回顾&#xff1a;Day 7 重点回顾 在 Day 7 中&#xff0c;我们彻底讲透了观察者模式&#xff1a; 它是典型的行为型模式&#xff0c;核心理念是“一变多知”&#xff0c;当一个对象状态变化时&#xff0c;自动通知所有订阅者。 我们通过 RxCpp 实现了工业…...

ONVIF/RTSP/RTMP协议EasyCVR视频汇聚平台RTMP协议配置全攻略 | 直播推流实战教程

在现代化的视频管理和应急指挥系统中&#xff0c;RTMP协议作为一种高效的视频流传输方式&#xff0c;正变得越来越重要。无论是安防监控、应急指挥&#xff0c;还是物联网视频融合&#xff0c;掌握RTMP协议的接入和配置方法&#xff0c;都是提升系统性能和效率的关键一步。 今天…...

单片机领域中哈希表

以下是单片机领域中哈希表的实际应用及编程实例&#xff1a; 1.哈希表在单片机中的实际应用场景 • 命令解析&#xff1a;在单片机通信中&#xff0c;经常需要解析接收到的命令。使用哈希表可以快速地将命令字符串映射到对应的处理函数&#xff0c;提高命令解析的效率。 • 数…...

《微服务与事件驱动架构》读书分享

《微服务与事件驱动架构》读书分享 Building Event-Driver Microservices 英文原版由 OReilly Media, Inc. 出版&#xff0c;2020 作者&#xff1a;[加] 亚当 • 贝勒马尔 译者&#xff1a;温正东 作者简介&#xff1a; 这本书由亚当贝勒马尔&#xff08;Adam Bellemare…...

每日一题(小白)暴力娱乐篇26

我们先直接尝试暴力循环四轮看能不能得到答案&#xff0c;条件&#xff1a;四个数的平方相加等于这个数 ①接收答案result ②循环四轮i&#xff0c;j&#xff0c;k&#xff0c;l ③如果i*ij*jk*kl*lresult ④按照要求的格式输出这四个数字 代码如下&#x1f447; public s…...

Compose笔记(十六)--ExoPlayer

这一节了解一下Compose中的ExoPlayer的使用&#xff0c;我们在开发Android应用时&#xff0c;经常会使用到播放器&#xff0c;这个ExoPlayer框架就相对成熟&#xff0c;易上手&#xff0c;现简单总结如下: 1. ExoPlayer 核心类 ExoPlayer 是 ExoPlayer库的核心类&#…...

如何使用AI辅助开发R语言

R语言是一种用于统计计算和图形生成的编程语言和软件环境&#xff0c;很多学术研究和数据分析的科学家和统计学家更青睐于它。但对与没有编程基础的初学者而言&#xff0c;R语言也是有一定使用难度的。不过现在有了通义灵码辅助编写R语言代码&#xff0c;我们完全可以用自然语言…...

Git版本管理系列:(三)远程仓库

目录 与远程仓库平台(github\gitee等)建立连接本地仓库关联远程仓库本地仓库内容推送远程仓库&#xff1a;PUSH将远程仓库的更新拉取到本地:PULL语法总结 与远程仓库平台(github\gitee等)建立连接 远程仓库平台相当于一个网盘&#xff0c;我们可以把自己的代码上传上去。就像网…...

React Hooks: useRef,useCallback,useMemo用法详解

1. useRef&#xff08;保存引用值&#xff09; useRef 通常用于保存“不会参与 UI 渲染&#xff0c;但生命周期要长”的对象引用&#xff0c;比如获取 DOM、保存定时器 ID、WebSocket等。 新建useRef.js组件&#xff0c;写入代码&#xff1a; import React, { useRef, useSt…...

STM32F103复用JTAG/SWD引脚为GPIO

普中-精灵1开发板&#xff0c;主芯片为STM32F103C8T6&#xff0c;4个独立按键K1~K4依次接PA15~PA12&#xff0c;按下为低电平&#xff0c;8个LED灯D1~D8&#xff0c;依次接PA0~PA7。查询手册得知&#xff1a;PA15主功能为JTDI&#xff0c;PA14为JTCK/SWCLK&#xff0c;PA13为JT…...

[wifi SAE]wpa3-personal

SAE &#xff1a;Simultaneous Authentication of Equals&#xff08;同等同时认证&#xff09; wpa2和wpa3之间最大的区别是认证过程的区别 WPA2不安全性 1.sta和ap预置psk(AP密码) 2.四次握手生成ptk用于后续数据加密的密钥 ptk计算基于psk、双方随机数&#xff1b; 双方都产…...

电路方案分析(二十)TPS63xxx系列DC/DC电源EMI PCB设计方案

tips&#xff1a;资料来自网络&#xff0c;仅供学习使用。[TOC](TPS63xxx系列DC/DC电源EMI PCB设计方案) 1.概述 通过TPS63xxx系列DC/DC电源模块来分析降低直流/直流降压/升压转换器辐射 EMI 的来源以及相关PCB设计。 下面都以最常用的TPS63070为例说明&#xff1a; 典型应用…...

DeepSeek 在金融领域的应用解决方案

DeepSeek 在金融领域的应用解决方案 一、背景 随着人工智能技术的快速发展&#xff0c;DeepSeek 作为一款国产大模型&#xff0c;凭借其强大的语义理解、逻辑推理和多模态处理能力&#xff0c;在金融行业迅速崭露头角。金融行业作为经济的核心&#xff0c;面临着激烈的市场竞…...

Java 大厂面试题 -- JVM 深度剖析:解锁大厂 Offe 的核心密钥

最近佳作推荐&#xff1a; Java大厂面试高频考点&#xff5c;分布式系统JVM优化实战全解析&#xff08;附真题&#xff09;&#xff08;New&#xff09; Java大厂面试题 – JVM 优化进阶之路&#xff1a;从原理到实战的深度剖析&#xff08;2&#xff09;&#xff08;New&#…...

【AI提示词】API开发专家

提示说明 API开发专家专注于设计和实现高效、稳定、安全的应用程序接口&#xff08;API&#xff09;。他们通过深入理解业务需求和用户场景&#xff0c;为用户提供定制化的API解决方案。 提示词 # 角色 API开发专家## 注意 1. 专家设计应考虑API开发过程中的技术细节和用户需…...

目标追踪Hyperspectral Adapter for Object Tracking based on Hyperspectral Video

论文作者&#xff1a;Long Gao,Yunhe Zhang,Langkun Chen,Yan Jiang,Weiying Xie,Yunsong Li 作者单位&#xff1a;Xidian University;the University of Sheffield 论文链接&#xff1a;http://arxiv.org/abs/2503.22199v1 内容简介&#xff1a; 1&#xff09;方向&#x…...

深度剖析SSD多段L2P表查找加速技术

在固态硬盘(SSD)控制器中,逻辑块地址(LBA)需要通过映射表(L2P Table)映射到NAND闪存的物理地址(PA)。随着SSD容量的增长,L2P表的大小也随之增加,这给查找操作带来了性能挑战。 在SSD控制器中,LBA需借助L2P表映射为NAND物理地址。映射表最小规模为 (O(n * \lg (n)))…...

【MQTT-协议原理】

MQTT-协议原理 ■ MQTT-协议原理■ MQTT-服务器 称为"消息代理"&#xff08;Broker&#xff09;■ MQTT协议中的订阅、主题、会话■ 一、订阅&#xff08;Subscription&#xff09;■ 二、会话&#xff08;Session&#xff09;■ 三、主题名&#xff08;Topic Name&a…...

PCIe 5.0光学SSD原型问世!

近日&#xff0c;Kioxia Corporation&#xff08;铠侠&#xff09;、AIO Core Co., Ltd. 和 Kyocera Corporation&#xff08;京瓷&#xff09;联合宣布成功开发了一款支持 PCIe 5.0 接口的光学 SSD 原型。该技术旨在通过光接口替换传统的电接口&#xff0c;从而显著增加计算设…...

Raymarching Textures In Depth

本节课最主要的就是学会hlsl中使用纹理采样 float4 color Texture2DSample(Texobj, TexobjSampler, uv); return color; 课程中的代码&#xff08;没有这张图我就没做&#xff09; 课程代码产生深度的原因是uv偏移&#xff0c;黑色区域会不断向左偏移&#xff0c;直到找到白色…...

maven编译jar踩坑[sqlite.db]

背景&#xff1a; 最近在项目中搞多数据源切换的job,在src/resource下有初始化的sqlite默认文件供后续拷贝使用&#xff0c;在测试阶段没有什么问题&#xff0c;但是一部署到服务器上运行就有问题。 报错现象&#xff1a; 找不到这个sqlite.db文件或者文件格式有问题&#x…...

文献总结:ECCV2022-BEVFormer

BEVFormer 一、文章基本信息二、文章背景三、BEVFormer架构(1) BEV 查询(2) 空间交叉注意力机制(3) 时间自注意力机制(4) BEV应用(5) 实施细节 四、实验五、总结 一、文章基本信息 标题BEVFormer: Learning Bird’s-Eye-view Representation from Multi-camera images via spa…...

Openlayers:海量图形渲染之WebGL渲染

最近由于在工作中涉及到了海量图形渲染的问题&#xff0c;因此我开始研究相关的解决方案。我在网络上寻找相关的解决方案时发现许多的文章都提到利用Openlayers中的WebGLPointsLayer类&#xff0c;可以实现渲染海量的点&#xff0c;之后我又了解到利用WebGLVectorLayer类可以渲…...

RCE漏洞学习

1&#xff0c;What is RCE&#xff1f; 在CTF&#xff08;Capture The Flag&#xff09;竞赛中&#xff0c;RCE漏洞指的是远程代码执行漏洞&#xff08;Remote Code Execution&#xff09;。这类漏洞允许攻击者通过某种方式在目标系统上执行任意代码&#xff0c;从而完全控制目…...

如何将网页保存为pdf

要将网页保存为PDF&#xff0c;可以按照以下几种方法操作&#xff1a; 1. 使用浏览器的打印功能 大多数现代浏览器&#xff08;如Chrome、Firefox、Edge等&#xff09;都支持将网页保存为PDF文件。步骤如下&#xff1a; 在 Google Chrome 中&#xff1a; 打开你想保存为PDF…...

什么是继承?js中有哪儿些继承?

1、什么是继承&#xff1f; 继承是面向对象软件技术中的一个概念。 2、js中有哪儿些继承&#xff1f; js中的继承有ES6的类class的继承、原型链继承、构造函数继承、组合继承、寄生组合继承。 2.1 ES6中类的继承 class Parent {constructor() {this.age 18;} }class Chil…...

如何使用 Grafana 连接 Easyearch

Grafana 介绍 Grafana 是一款开源的跨平台数据可视化与监控分析工具&#xff0c;专为时序数据&#xff08;如服务器性能指标、应用程序日志、业务数据等&#xff09;设计。它通过直观的仪表盘&#xff08;Dashboards&#xff09;帮助用户实时监控系统状态、分析趋势&#xff0…...

mindsdb AI 开源的查询引擎 - 用于构建 AI 的平台,该平台可以学习和回答大规模联合数据的问题。

一、软件介绍 文末提供源码和程序下载学习 MindsDB 是一种解决方案&#xff0c;使人类、AI、代理和应用程序能够以自然语言和 SQL 查询数据&#xff0c;并在不同的数据源和类型中获得高度准确的答案。此开源程序是一个联合查询引擎&#xff0c;可以整理您的数据蔓延混乱&#…...

802.11a ofdm 过程了解

ofdm_demo.py import numpy as np from scipy import interpolate import commpy as cpy import ofdm_debug as ofdm_debug class OFDMSystem:def __init__(self, K64, CPNone, P8, pilotValue33j, Modulation_typeQAM16, channel_typerandom, SNRdb25,debugFalse):# 设置OFDM…...

BOTA六维力矩传感器如何打通机器人AI力控操作的三层架构?感知-决策-执行全链路揭秘

想象一下&#xff0c;你对着一个机器人说&#xff1a;“请帮我泡杯茶。”然后&#xff0c;它就真的开始行动了&#xff1a;找茶壶、烧水、取茶叶、泡茶……这一切看似简单&#xff0c;但背后却隐藏着复杂的AI技术。今天&#xff0c;我们就来揭秘BOTA六维力矩传感器在机器人操控…...