谈谈策略模式,策略模式的适用场景是什么?

news2025/4/7 21:44:31
一、什么是策略模式?​

策略模式(Strategy Pattern)属于​​行为型设计模式​​。核心思路是将一组​​可替换的算法​​封装在独立的类中,使它们可以在运行时动态切换,同时使客户端代码与具体算法解耦。它包含三个核心角色:

  1. ​策略接口(Strategy Interface)​​:定义算法的方法签名
  2. ​具体策略(Concrete Strategies)​​:实现具体算法逻辑
  3. ​上下文(Context)​​:持有一个策略对象,并调用其方法

​通俗比喻​​:把算法当作「插件」,客户端只需要选择对应插件插入到主流程中,不需要关注插件内部实现。


​二、适用场景​

_以下场景常见于前端开发:_

  1. ​同类功能的多算法切换​
    👉 表单验证(邮箱、手机号、身份证等校验规则)、数据导出(CSV、Excel、PDF格式)、图表渲染(折线图、柱状图)
  2. ​需要动态选择行为的场景​
    👉 动态折扣计算(满减、折扣券、积分抵扣)、权限校验(不同角色对应不同校验规则)
  3. ​消除臃肿的条件分支​
    👉 存在大量 if-else 或 switch-case 的场景(如老代码中的支付方式处理)
  4. ​需要隐藏复杂算法的实现​
    👉 地图路径规划(步行、驾车、公交策略)、动画缓动函数(linear、ease-in)

​三、实战代码示例​
​案例1:表单验证策略​
// 策略接口:定义 validate 方法
class ValidationStrategy {
  validate(value) {
    throw new Error("必须实现 validate 方法!");
  }
}

// 具体策略:非空校验
class RequiredValidation extends ValidationStrategy {
  validate(value) {
    return value.trim() !== "";
  }
}

// 具体策略:手机号校验
class MobileValidation extends ValidationStrategy {
  validate(value) {
    return /^1[3-9]\d{9}$/.test(value);
  }
}

// 上下文类:管理当前策略
class ValidatorContext {
  constructor(strategy) {
    this.strategy = strategy;
  }

  setStrategy(strategy) {
    this.strategy = strategy;
  }

  execute(value) {
    return this.strategy.validate(value);
  }
}

// 使用示例
const validator = new ValidatorContext(new RequiredValidation());
console.log(validator.execute("")); // 输出 false

validator.setStrategy(new MobileValidation());
console.log(validator.execute("13800138000")); // 输出 true

​代码亮点​​:

  • 添加新校验规则只需新增策略类,无须修改 ValidatorContext
  • 客户端通过 .setStrategy() 动态切换算法

​案例2:动态数据导出(常用功能增强)​
// 策略接口:导出方法
class ExportStrategy {
  export(data) {
    throw new Error("必须实现 export 方法");
  }
}

// 具体策略-导出为 CSV
class CsvExport extends ExportStrategy {
  export(data) {
    const csvContent = data.map(row => row.join(",")).join("\n");
    console.log(`导出 CSV 成功,内容:${csvContent}`);
  }
}

// 具体策略-导出为 Excel(伪代码)
class ExcelExport extends ExportStrategy {
  export(data) {
    // 假装调用了 Excel 库
    console.log("生成 Excel 文件并下载");
  }
}

// 上下文(可与 UI 结合)
class Exporter {
  constructor() {
    this.strategy = new CsvExport(); // 默认策略
  }

  setFormat(format) {
    if (format === 'csv') {
      this.strategy = new CsvExport();
    } else if (format === 'excel') {
      this.strategy = new ExcelExport();
    }
  }

  executeExport(data) {
    this.strategy.export(data);
  }
}

// 使用示例
const exporter = new Exporter();
exporter.setFormat('excel');
exporter.executeExport([['Name', 'Age'], ['John', 30]]);

​应用场景​​:
不同导出格式的代码集中到策略类中,避免主模块代码混乱。


​四、开发建议与避坑指南​
​推荐做法​​:
  1. ​组合优于继承​​:
    用策略对象组合到上下文类,而非通过继承实现多态
  2. ​接口约束​​:TypeScript 更优
    interface Strategy {
      execute(data: any): void;
    }
  3. ​策略命名清晰​​:
    用 MobileValidationStrategy 而非 Strategy1,便于维护
  4. ​无状态策略​​:
    尽量将策略设计为无状态(纯函数),可通过单例复用
​常见陷阱​​:
  1. ​过度设计​​:
    👉 若只有1~2种固定算法,直接 if-else 更简单
  2. ​客户端感知策略细节​​:
    👉 违反迪米特法则,应当由上下文类处理策略选择
  3. ​策略间参数不一致​​:
    👉 校验策略统一接收字符串,而非有的需要 value,有的需要 formData
  4. ​性能损耗​​:
    👉 频繁创建策略对象时,可考虑对象池缓存

策略模式是应对​​算法多样化​​和​​动态切换需求​​的强大工具,前端开发中使用频率较高。

正确使用可显著提升代码可维护性,但在简单场景下需权衡是否引入复杂度。关键在于​​识别行为的变化点​​,将其独立出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2330074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从零构建大语言模型全栈开发指南:第四部分:工程实践与部署-4.2.3行业案例:智能客服中的图文交互系统

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 从零构建大语言模型全栈开发指南-第四部分:工程实践与部署4.2.3 行业案例:智能客服中的图文交互系统1. 图文交互系统的核心挑战与价值2. 系统架构设计2.1 分层架构2.2 Adapter技术应用3. 行业应用案例…

华为IP(4)

VRRP(虚拟路由冗余协议) 前言: 局域网中的用户终端通常采用配置一个默认网关的形式访问外部网络,如果默认网关设备发生故障,那么所有用户终端访问外部网络的流量将会中断。可以通过部署多个网关的方式来解决单点故障…

计算机网络中科大 - 第1章 结构化笔记(详细解析)

博主主页 目录 **1. 计算机网络概述****1.1 计算机网络的定义****1.2 计算机网络的发展** **2. 计算机网络的组成与分类****2.1 计算机网络的组成****2.2 计算机网络的分类****按地理范围****按拓扑结构****按交换方式** **3. 计算机网络的性能指标****4. 计算机网络体系结构**…

【神经网络】python实现神经网络(三)——正向学习的模拟演练

有了之前的经验(【神经网络】python实现神经网络(二)——正向推理的模拟演练),我们继续来介绍如何正向训练神经网络中的超参(包含权重以及偏置),本章大致的流程图如下: 一.损失函数 神经网络以某个指标为基准寻求最优权重参数,而这个指标即可称之为 “损失函数” 。(…

PPTAgent:一款开源免费生成和评估幻灯片的项目

这篇文章介绍一下PPTAgent,一个从文档自动生成演示文稿的创新系统。该系统从人类的展示创作方法中汲取灵感,采用两步流程来确保卓越的整体质量。此外,本文还介绍了PPTEval,这是一个综合评估框架,可以跨多个维度评估演示…

Java 大视界 -- Java 大数据在智能供应链库存优化与成本控制中的应用策略(172)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

斯坦福大学李飞飞团队新突破!FlowMo 革新图像 Tokenizer

当我们悠然刷着手机,看到一张可爱猫咪的照片时,大脑会瞬间识别出「这是一只猫」,这一切不过是电光火石间的事儿。但在计算机的 “眼中”,情况却复杂得超乎想象。假设这是一张10001000像素的彩色照片,在计算机的世界里&…

博客文章:深入分析 PyMovie - 基于 Python和 MoviePy 的视频管理工具

这是一个使用 wxPython 构建界面、moviepy 处理视频的自定义 GUI 应用程序。该工具提供了视频播放、元数据提取、格式转换、视频裁剪和截图等功能。通过分析其设计和实现,我们将了解其工作原理、优点和潜在的改进空间。 C:\pythoncode\new\output\pymovieSample.py …

2025年渗透测试面试题总结-某 携程旅游-基础安全工程师(题目+回答)

网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 携程旅游-基础安全工程师 反序列化原理 核心原理 扩展分析 SQL注入本质 核心原理 扩展分析 SQL注…

niuhe插件, 在 go 中渲染网页内容

思路 niuhe 插件生成的 go 代码是基于 github.com/ma-guo/niuhe 库进行组织管理的, niuhe 库 是对 go gin 库的一个封装,因此要显示网页, 可通过给 gin.Engine 指定 HTMLRender 来实现。 实现 HTMLRender 我们使用 gitee.com/cnmade/pongo2gin 实现 1. main.go …

使用MySQL时出现 Ignoring query to other database 错误

Ignoring query to other database 错误 当在远程连接软件中输入MySQL命令出现该错误 导致错误原因是:登录mysql时账户名没有加上u 如果出现该错误,退出mysql,重新输入正确格式进入即可!

java后端开发day34--脑子空空如何无痛想起所有知识点--概念拟人化

1.上半部学习思考 1.1反思–浮躁–二倍速 刚开始算半个小白吧,从最基础的知识点开始学习,到后面学习整个项目的布局和功能。可能是后面慢慢懂得多了,每次打代码搞项目啊什么的,就能明显感觉到自己很浮躁:脑子里已经明…

fastGPT—前端开发获取api密钥调用机器人对话接口(HTML实现)

官网文档链接&#xff1a;OpenAPI 介绍 | FastGPT 首先按照文档说明创建api密钥 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sca…

解决 PDF 难题:批量处理、文档清理与自由拆分合并

软件介绍 在日常办公与学习中&#xff0c;处理 PDF 文件常常让人头疼不已&#xff0c;不过别担心&#xff0c;今天有一款堪称神器的国产老牌 PDF 工具要分享给大家。它就是 PDF 补丁丁&#xff0c;凭借其强大功能&#xff0c;为大家排忧解难。 界面体验 初次打开 PDF 补丁丁&…

使用pycharm社区版调试DIFY后端python代码

目录 背景 前置条件 DIFY使用的框架 API服务调试配置步骤&#xff08;基于tag为0.15.3的版本&#xff09; 1.配置.env文件 2.关闭docker里面的docker-api-1服务 3.使用DOCKER启动本地环境需要用到的中间件&#xff0c;并暴露端口 注意事项一&#xff1a; 注意事项二&#xff1a…

量子计算与人工智能的结合:未来科技的双重革命

引言 在过去几十年里&#xff0c;人工智能&#xff08;AI&#xff09;和计算能力的提升一直是推动科技进步的重要力量。然而&#xff0c;随着深度学习和大规模数据处理的发展&#xff0c;传统计算架构的算力瓶颈逐渐显现&#xff0c;人工智能的训练和推理效率受到了限制。在此背…

关于存储的笔记

存储简介 名称适用场景常见运用网络环境备注块存储高性能、低延迟数据库局域网专业文件存储数据共享共享文件夹、非结构化数据局域网通用对象存储大数据、云存储网盘、网络媒体公网&#xff08;断点续传、去重&#xff09;海量 存储协议 名称协议块存储FC-SAN或IP-SAN承载的…

JWT认证服务

JSON Web Token&#xff08;JWT&#xff09;是一种用于在网络应用间安全地传递信息的紧凑、自包含的方式。以下是关于 JWT 认证服务器更详细的介绍&#xff0c;包括其意义、作用、工作原理、组成部分、时效性相关内容、搭建条件以及代码案例。 JWT 的意义与作用 意义&#xf…

手机中的type-C是如何防水的呢?

防水类型的type-C座子&#xff1a; 电子产品防水等级的区分&#xff1a; 这里的“IP”是国际防护标准等级&#xff1b;简而言之&#xff0c;IPXX中“XX”两位数字分别代表防尘和防水等级&#xff0c;其中防尘等级从0&#xff5e;6&#xff0c;防水等级则从0&#xff5e;8。 第…

[Redis]Redis学习开篇概述

欢迎来到啾啾的博客&#x1f431;。 这是一个致力于构建完善 Java 程序员知识体系的博客&#x1f4da;。 它记录学习点滴&#xff0c;分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 欢迎评论交流&#xff0c;感谢您的阅读&#x1f604;。 引言 大家好…