【前端设计模式】之策略模式
概述
在前端开发中,我们经常会遇到需要根据不同的条件或情况来执行不同的算法或行为的情况。这时,策略模式就能派上用场。策略模式是一种行为型设计模式,它将不同的算法封装成独立的策略对象,使得这些算法可以互相替换,而不影响客户端代码。这种灵活性和可扩展性使得策略模式在前端开发中得到广泛应用。
前端应用示例
1. 抽象策略类
假设我们正在开发一个电商网站,在商品详情页需要根据不同的促销活动来计算商品的折扣价格。我们可以使用策略模式来处理这种情况。
首先,我们定义一个抽象策略类 DiscountStrategy
,其中包含一个抽象方法 calculateDiscount
用于计算折扣价格。
class DiscountStrategy {calculateDiscount(price) {// 抽象方法,具体实现由子类实现}
}
然后,我们创建具体的策略类,如 FixedDiscountStrategy
(固定折扣)和 PercentageDiscountStrategy
(百分比折扣),它们分别实现了 calculateDiscount
方法来计算不同的折扣价格。
class FixedDiscountStrategy extends DiscountStrategy {calculateDiscount(price) {return price - 10; // 固定折扣10元}
}class PercentageDiscountStrategy extends DiscountStrategy {calculateDiscount(price) {return price * 0.8; // 百分比折扣,打八折}
}
最后,在商品详情页的代码中,根据不同的促销活动选择合适的策略对象,并调用其 calculateDiscount
方法来计算商品的折扣价格。
const price = 100; // 商品原价let discountStrategy;if (isFixedDiscount) {discountStrategy = new FixedDiscountStrategy();
} else if (isPercentageDiscount) {discountStrategy = new PercentageDiscountStrategy();
}const discountedPrice = discountStrategy.calculateDiscount(price);
这样,当需要新增或修改促销策略时,只需创建或修改相应的策略对象即可,而不需要修改商品详情页的代码。这提高了代码的可维护性和可扩展性。
2. 优化if else代码
当需要根据不同的条件执行不同的代码逻辑时,使用策略模式可以优化if else代码。下面是一个前端策略模式优化if else代码的示例:
// 定义策略对象
const strategies = {option1: function() {// 执行选项1的逻辑},option2: function() {// 执行选项2的逻辑},option3: function() {// 执行选项3的逻辑}
};// 定义上下文对象
const context = {executeStrategy: function(strategyName) {const strategy = strategies[strategyName];if (strategy) {strategy();} else {// 处理未知策略的情况}}
};// 使用示例
context.executeStrategy('option1'); // 执行选项1的逻辑
context.executeStrategy('option2'); // 执行选项2的逻辑
context.executeStrategy('option3'); // 执行选项3的逻辑
在上面的示例中,我们首先定义了一个包含不同策略函数的strategies
对象。然后,我们定义了一个上下文对象context
,其中包含了一个executeStrategy
方法,该方法接受一个策略名称作为参数,并根据该名称执行相应的策略函数。
3. 实现加减乘除
// 定义一个策略对象
const strategies = {add: function(a, b) {return a + b;},subtract: function(a, b) {return a - b;},multiply: function(a, b) {return a * b;},divide: function(a, b) {return a / b;}
};// 定义一个执行操作的函数
function executeOperation(operation, a, b) {if (strategies.hasOwnProperty(operation)) {return strategies[operation](a, b);} else {throw new Error('Unsupported operation');}
}// 使用示例
console.log(executeOperation('add', 5, 3)); // 输出: 8
console.log(executeOperation('subtract', 5, 3)); // 输出: 2
console.log(executeOperation('multiply', 5, 3)); // 输出: 15
console.log(executeOperation('divide', 6, 2)); // 输出: 3
console.log(executeOperation('power', 2, 3)); // 抛出错误:Unsupported operation
在上面的示例中,我们定义了一个strategies
对象,它包含了不同的操作(add、subtract、multiply和divide)作为属性,并且每个属性对应一个执行该操作的函数。然后,我们定义了一个executeOperation
函数,它接受一个操作名称和两个参数,并根据操作名称调用相应的策略函数来执行操作。
通过使用策略模式,我们可以轻松地添加新的操作或修改现有的操作,而不需要修改executeOperation
函数的代码。这样可以提高代码的可维护性和可扩展性。
4. 表单验证
在表单验证中,可以使用策略模式来定义不同的验证规则,并根据不同的规则来执行相应的验证操作。
const validationStrategies = {required: function(value) {return value !== '';},email: function(value) {return /^[^\s@]+@[^\s@]+.[^\s@]+$/.test(value);},minLength: function(value, length) {return value.length >= length;}
};function validateField(value, rules) {for (let rule of rules) {const [strategy, ...params] = rule.split(':');if (validationStrategies.hasOwnProperty(strategy)) {const isValid = validationStrategies[strategy](value, ...params);if (!isValid) {return false;}} else {throw new Error('Unsupported validation strategy');}}return true;
}// 使用示例
const emailValue = 'test@example.com';
const emailRules = ['required', 'email'];
console.log(validateField(emailValue, emailRules)); // 输出: trueconst passwordValue = '123';
const passwordRules = ['required', 'minLength:6'];
console.log(validateField(passwordValue, passwordRules)); // 输出: false
5. 动态组件渲染
在动态组件渲染中,可以使用策略模式来根据不同的条件或状态选择性地渲染不同的组件。
const componentStrategies = {home: function() {return <HomeComponent />;},profile: function() {return <ProfileComponent />;},settings: function() {return <SettingsComponent />;}
};function renderComponent(page) {if (componentStrategies.hasOwnProperty(page)) {return componentStrategies[page]();} else {throw new Error('Unsupported page');}
}// 使用示例
const currentPage = 'profile';
const component = renderComponent(currentPage);
ReactDOM.render(component, document.getElementById('app'));
6. 数据转换和格式化
在数据转换和格式化中,可以使用策略模式来定义不同的转换规则,并根据不同的规则来执行相应的转换操作。
const formatStrategies = {currency: function(value) {return `$${value.toFixed(2)}`;},percentage: function(value) {return `${(value * 100).toFixed(2)}%`;},uppercase: function(value) {return value.toUpperCase();}
};function formatData(data, format) {if (formatStrategies.hasOwnProperty(format)) {return formatStrategies[format](data);} else {throw new Error('Unsupported format');}
}// 使用示例
const amount = 10.5;
console.log(formatData(amount, 'currency')); // 输出: $10.50const rate = 0.75;
console.log(formatData(rate, 'percentage')); // 输出: 75.00%const name = 'john doe';
console.log(formatData(name, 'uppercase')); // 输出: JOHN DOE
这些只是前端策略模式的一些常见应用场景,实际上,策略模式可以应用于任何需要根据不同的条件或情况来执行不同操作的场景。
优缺点
优点
- 可扩展性:新增或修改算法变得简单,只需添加或修改相应的策略对象即可,而不需要修改客户端代码。
- 可维护性:代码结构更清晰、可读性更高,易于维护和理解。
- 可复用性:策略对象可以在不同的场景中被复用,避免了重复编写相似的代码。
- 松耦合:客户端与具体的策略对象解耦,客户端只需要知道如何使用策略对象即可。
缺点
- 增加了类和对象的数量:引入了多个策略对象会增加类和对象的数量,可能会增加系统复杂度。
- 客户端需要了解所有的策略:客户端需要知道所有可用的策略,并选择合适的策略进行使用。
总结
前端设计模式之策略模式是一种强大而灵活的模式,在处理不同算法或行为时能够提供良好的解决方案。通过将不同的算法封装成独立的策略对象,策略模式使得代码更加可维护、可扩展和可复用。在前端开发中,合理应用策略模式能够提高代码质量和开发效率。
相关文章:
【前端设计模式】之策略模式
概述 在前端开发中,我们经常会遇到需要根据不同的条件或情况来执行不同的算法或行为的情况。这时,策略模式就能派上用场。策略模式是一种行为型设计模式,它将不同的算法封装成独立的策略对象,使得这些算法可以互相替换࿰…...

JUC包(面试常问)
1. Callable接口 类似于Runnable接口,Runnable描述的任务,不带返回值;Callable描述的任务带返回值。 public class Test {//创建线程,计算12...1000public static void main(String[] args) throws ExecutionException, Interru…...

文字处理工具Word mac软件特点
Microsoft Word mac是一款文字处理软件。它是 Microsoft office 套件的一部分,已广泛用于创建、编辑和格式化文本文档。 Word mac软件特点 改进的协作工具:使用 Microsoft Word 2021,多个用户可以同时处理一个文档,从而更轻松地与…...

把 Windows 11 装进移动硬盘:Windows 11 To Go
本篇文章聊聊如何制作一个可以“说带走就带走”的 Windows 操作系统,将 Windows11 做成能够放在 U 盘或者移动硬盘里的 WinToGo “绿色软件”。 写在前面 在《开源的全能维护 U 盘工具:Ventoy》这篇文章的最后,我提到了一个关键词 “WinToG…...

11、pytest断言预期异常
官方用例 # content of test_exception_zero.py import pytestdef test_zero_division():with pytest.raises(ZeroDivisionError):1/0# content of test_exception_runtimeerror.py import pytestdef test_recursion_depth():with pytest.raises(RuntimeError) as excinfo:def…...

Vue之数据绑定
在我们Vue当中有两种数据绑定的方法 1.单向绑定 2.双向绑定 让我为大家介绍一下吧! 1、单向绑定(v-bind) 数据只能从data流向页面 举个例子: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"…...
druid在没有web的项目中如何查看监控
(1)在这个网址下载druidStat.bat文件https://github.com/alibaba/druid/blob/master/core/src/main/scripts/druidStat.bat druidStat.bat文件内容如下: echo offset _RUNJAVA"%JAVA_HOME%\bin\java.exe" set _TOOLSJAR"%JA…...
游戏被攻击该怎么办?游戏盾该如何使用,游戏盾如何防护攻击
随着Internet互联网络带宽的增加和多种DDOS黑客工具的不断发布,DDOS拒绝服务攻击的实施越来越容易,DDOS攻击事件正在成上升趋势。出于商业竞争、打击报复和网络敲诈等多种因素,导致很多商业站点、游戏服务器、聊天网络等网络服务商长期以来一…...

【基于openGauss5.0.0简单使用DBMind】
基于openGauss5.0.0简单使用DBMind 一、环境说明二、初始化tpch测试数据三、使用DBMind索引推荐功能四、使用DBMind实现SQL优化功能 一、环境说明 虚拟机:virtualbox操作系统:openEuler 20.03 TLS数据库:openGauss-5.0.0DBMind:d…...

[递归回溯]连接卡片最短路径
小游戏 题目描述 一天早上,你起床的时候想:“我编程序这么牛,为什么不能靠这个挣点银子呢?”因此你决定编写一个小游戏。 游戏在一个分割成w * h个长方格子的矩形板上进行。如图所示,每个长方格子上可以有一张游戏…...

初识人工智能,一文读懂强化学习的知识文集(5)
🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…...

视频封面提取:精准截图,如何从指定时长中提取某一帧图片
在视频制作和分享过程中,一个有吸引力的封面或截图往往能吸引更多的观众点击观看。有时候要在特定的时间段内从视频中提取一帧作为封面或截图。如果每个视频都手动提取的话就会耗费很长时间,那么如何智化能批量提取呢?现在一起来看下云炫AI智…...
Shopify 开源 WebAssembly 工具链 Ruvy
最近,Spotify 开源了Ruvy,一个 WebAssembly 工具链,能够将 Ruby 代码转换为 Wasm 模块。Ruvy 基于ruby.wasm, 用 Rust 实现,提升了性能并简化了 Wasm 模块的执行。 Ruvy 利用了ruby.wasm提供的 Ruby 解释器模块,并使用wasi-vfs (WASI 虚拟文件系统)将其与所有指定的 Rub…...

zxjy008- 项目集成Swagger
Swagger可以生成在线文档,还可以进行接口测试。 1、创建common模块(maven类型) 为了让所有的微服务子子模块都可以使用,可以在guli_parent父工程下面创建公共模块 1.1 在guli_parent父工程下面创建公共模块 配置: groupId:com…...

使用linux CentOS本地部署SQL Server数据库
🌈个人主页:聆风吟 🔥系列专栏:数据结构、Cpolar杂谈 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 安装sql server二. 局域网测试连接三. 安装cpolar内网穿透四. 将sqlserver映射…...

理解基于 Hadoop 生态的大数据技术架构
转眼间,一年又悄然而逝,时光荏苒,岁月如梭。当回首这段光阴,不禁感叹时间的匆匆,仿佛只是一个眨眼的瞬间,一年的旅程已成为过去,而如今又到了画饼的时刻了 ! 基于 Hadoop 生态的大数…...

【Go】Go语言基础内容
变量声明: 变量声明:在Go中,变量必须先声明然后再使用。声明变量使用 var 关键字,后面跟着变量名和类型,如下所示: var age int这行代码声明了一个名为 age 的整数变量。 变量初始化:您可以在声…...
HP-UNIX 系统安全基线 安全加固操作
目录 账号管理、认证授权 账号 ELK-HP-UX-01-01-01 ELK -HP-UX-01-01-02 ELK -HP-UX-01-01-03 ELK-HP-UX-01-01-04 ELK-HP-UX-01-01-05 口令 ELK-HP-UX-01-02-01 ELK-HP-UX-01-02-02 ELK-HP…...

第九天:信息打点-CDN绕过篇amp;漏洞回链amp;接口探针amp;全网扫描amp;反向邮件
信息打点-CDN绕过篇 cdn绕过文章:https://www.cnblogs.com/qiudabai/p/9763739.html 一、CDN-知识点 1、常见访问过程 1、没有CDN情况下传统访问:用户访问域名-解析服务器IP–>访问目标主机 2.普通CDN:用户访问域名–>CDN节点–>…...

【利用二手车数据进行可视化分析】
利用二手车数据进行可视化分析 查看原始数据去除重复数据需求分析1.统计全国总共有多少量二手车,用KPI图进行展示2.统计安徽总共有多少量二手车,用KPI图进行展示3.统计合肥总共有多少量二手车,用KPI图进行展示4.取最贵的10辆二手车信息&#…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...

uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...