【前端设计模式】之策略模式

概述

在前端开发中,我们经常会遇到需要根据不同的条件或情况来执行不同的算法或行为的情况。这时,策略模式就能派上用场。策略模式是一种行为型设计模式,它将不同的算法封装成独立的策略对象,使得这些算法可以互相替换,而不影响客户端代码。这种灵活性和可扩展性使得策略模式在前端开发中得到广泛应用。

前端应用示例

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

这些只是前端策略模式的一些常见应用场景,实际上,策略模式可以应用于任何需要根据不同的条件或情况来执行不同操作的场景。

优缺点

优点

  • 可扩展性:新增或修改算法变得简单,只需添加或修改相应的策略对象即可,而不需要修改客户端代码。
  • 可维护性:代码结构更清晰、可读性更高,易于维护和理解。
  • 可复用性:策略对象可以在不同的场景中被复用,避免了重复编写相似的代码。
  • 松耦合:客户端与具体的策略对象解耦,客户端只需要知道如何使用策略对象即可。

缺点

  • 增加了类和对象的数量:引入了多个策略对象会增加类和对象的数量,可能会增加系统复杂度。
  • 客户端需要了解所有的策略:客户端需要知道所有可用的策略,并选择合适的策略进行使用。

总结

前端设计模式之策略模式是一种强大而灵活的模式,在处理不同算法或行为时能够提供良好的解决方案。通过将不同的算法封装成独立的策略对象,策略模式使得代码更加可维护、可扩展和可复用。在前端开发中,合理应用策略模式能够提高代码质量和开发效率。

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

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

相关文章

ALPHA开发板烧录工具MfgTool简介

一. 简介 前面我们已经移植好了 uboot 和 linux kernle &#xff0c;制作好了根文件系统。但是我们移植都是通 过网络来测试的&#xff0c;在实际的产品开发中肯定不可能通过网络来运行。 因此&#xff0c;我们需要将 uboot 、 linux kernel 、 .dtb( 设备树 ) 和 rootf…

串口环形收发原理及实现

一、环形收发队列构建 1、构造环形收发数组及其长度 #define buff_size 10 Unsigned char buff[buff_size]; 2、定义环形收发读/写位置 u16 R_Buff; u16 W_Buff; 3、结构体封装 typedef struct Qbuff {u16 write; //写位置u16 read; //读位置u8 buf…

Zabbix自定义飞书webhook告警媒介1

说明&#xff1a;此配置仅适用于7版本及以上&#xff0c;低版本可能有问题 JavaScript 内容如下&#xff1a; try {var sourceData JSON.parse(value),req new HttpRequest(),response;if (sourceData.HTTPProxy) {req.setProxy(sourceData.HTTPProxy);}req.addHeader(Conte…

手机拍摄的照片复制到CSDN博客中自动旋转的问题的解决

概要&#xff1a;写CSDN博客的时候&#xff0c;复制手机拍摄的照片到博客中&#xff0c;照片会自动发生90度旋转。目前找到了两个解决方法。问题出现的环境是Ubuntu22.04Firefox120.0.1 方法一&#xff1a;用shutter打开重新保存 选中图片——>鼠标右键——>选择用其他软…

pytorch中的transpose用法

注意&#xff1a;维数从0开始&#xff0c;0维 1维2维…,负数代表从右往左数&#xff0c;-1代表第一维&#xff0c;以此类推 import torch import numpy as np# 创建一个二维数组 arr torch.tensor([[[1, 2],[3, 4]],[[5, 6],[7, 8]]]) print("原始数组&#xff1a;"…

python操作MySQL——封装增删改查

上一篇&#xff1a;python操作MySQL数据——连接与插入数据-CSDN博客 下一篇&#xff1a;python操作mysql——批量添加csv数据-CSDN博客 import pymysql.cursors from pymysql.err import OperationalError from data.readCsv import Csv_to_lst import os import configpar…

Docker部署.NET6项目

Docker的三大核心概念 1、docker仓库&#xff08;repository&#xff09; docker仓库&#xff08;repository&#xff09;类似于代码库&#xff0c;是docker集中存放镜像的场所。实际上&#xff0c;注册服务器是存放仓库的地方&#xff0c;其上往往存放着很多仓库。每个仓库集…

案例058:基于微信小程序的智能社区服务系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

操作符(原码反码补码)

目录 前言&#xff1a; 原反补码&#xff1a; 位操作符&#xff1a; &#xff06; &#xff5c; &#xff3e; &#xff5e; >> << 总结&#xff1a; 逻辑操作符 && || 其他操作符&#xff1a; sizeof -- () &#xff1f;&#xf…

AMEYA360--罗姆与Quanmatic公司利用量子技术优化制造工序并完成验证

全球知名半导体制造商罗姆(总部位于日本京都市)于2023年1月起与 Quanmatic Inc.(总部位于日本东京都新宿区&#xff0c;以下简称“Quanmatic”)展开合作&#xff0c;在半导体制造工序之一的EDS工序中测试并引入量子技术&#xff0c;以优化制造工序中的组合。目前&#xff0c;双…

C#excel导入dategridview并保存到数据库/dategridview增加一行或几行一键保存数据库

excel导入到dategridview显示并保存到数据库 dategridview增加一行或几行一键保存数据库 ExcelHelper类(这个要导入NPOI包) using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; using System.Collections.Generic; using Syste…

dtaidistance笔记:dtw_ndim (高维时间序列之间的DTW)

1 数据 第一个维度是sequence的index&#xff0c;每一行是多个元素&#xff08;表示这一时刻的record&#xff09; from dtaidistance.dtw_ndim import *s1 np.array([[0, 0],[0, 1],[2, 1],[0, 1],[0, 0]], dtypenp.double) s2 np.array([[0, 0],[2, 1],[0, 1],[0, .5],[0…

Elasticsearch--解决磁盘使用率超过警戒水位线

原文网址&#xff1a;Elasticsearch--解决磁盘使用率超过警戒水位线_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何解决ES磁盘使用率超过警戒水位线的问题。 问题描述 当客户端向 Elasticsearch 写入文档时候报错&#xff1a; cluster_block_exception [FORBIDDEN/12/inde…

超越节点引擎临界:华为云NES颠覆游戏规则

在技术领域&#xff0c;创新是引人注目的产物。华为云Web3节点引擎服务NES&#xff08;以下简称&#xff1a;华为云NES&#xff09;以卓越的技术实力赢得业内良好口碑。在近期SUSTAINABLE WEB3 SG 2023&#xff0c;华为云NES发表一系列性能优化成果及开发者支持计划&#xff0c…

Qt进程和线程

一、进程 在设计一个应用程序时,有时不希望将一个不太相关的功能集成到程序中,或者是因为该功能与当前设计的应用程序联系不大,或者是因为该功能已经可以使用现成的程序很好的实现了,这时就可以在当前的应用程序中调用外部的程序来实现该功能,这就会使用到进程。Qt应用程序…

亿胜盈科 HT4182,HT4186,HT4188 电量均衡 同步升压型 双节理电池充电器

HT4182&#xff0c;HT4186&#xff0c;HT4188是一款5V输入&#xff0c;升压模式的充电管理IC&#xff0c;适用于双节串联鲤电池。其能自适应任意5V电源进行充电&#xff0c;并且由输入过压、欠压保护。 HT4182&#xff0c;HT4186&#xff0c;HT4188采用同步升压结构&#xff0…

基于单片机出租车计价器控制系统

**单片机设计介绍&#xff0c;基于单片机出租车计价器控制系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的出租车计价器控制系统是一个用于控制和管理出租车费用计算的电子设备。下面是一个简单的系统设计介绍&…

Windows 下 PyTorch 入门深度学习环境安装与配置 GPU 版

1.确定自己的硬件信息&#xff0c;确定电脑有英伟达 (NVIDIA)显卡 在任务栏上右键打开任务管理器 2.下载安装 Anaconda &#xff08;建议安装迅雷下载&#xff0c;同时浏览器添加扩展 “迅雷Chrome支持”&#xff09; https://www.anaconda.com/ https://repo.anaconda.com/arc…

文本编辑软件:Ulysses mac介绍说明

Ulysses mac是面向 Mac、iPhone 和 iPad 的一站式写作环境。Ulysses 提供令人愉悦、专注的写作体验&#xff0c;加上高效文稿管理、无缝同步以及灵活导出。markdown 可以直接对于文本进行不同类型的分类、编辑&#xff0c;比如标题、注解、评论之类的内容。 Ulysses让注意力专…

手机号,邮箱,密码,验证码正则表达式[Java]

Util类&#xff1a; public abstract class RegexPatterns {/*** 手机号正则*/public static final String PHONE_REGEX "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$";/*** 邮箱正则*/public static final String EMAIL_REGEX "^[a-zA-Z…