使用策略模式优化多重if/else
一、为什么需要策略模式?
作为前端程序员,我们经常会遇到这样的场景,例如
进入一个营销活动页面,会根据后端下发的不同 type ,前端页面展示不同的弹窗。
async getMainData() {try {const res = await activityQuery(); // 请求后端数据this.styleType = res.styleType;if (this.styleType === STYLE_TYPE.Reward) {this.openMoneyPop();}else if (this.styleType === STYLE_TYPE.Waitreward) {this.openShareMoneyPop();} else if (this.styleType === STYLE_TYPE.Poster) {this.openPosterPop();} else if (this.styleType === STYLE_TYPE.Activity) {this.openActivityPop();} else if (this.styleType === STYLE_TYPE.Balance) {this.openBalancePop();} else if (this?.styleType === STYLE_TYPE.Cash) {this.openCashBalancePop();}} catch (error) {log.error(MODULENAME, '主接口异常', JSON.stringify(error));}
}
我们在写的时候也许不觉得,但是当我们去维护别人的代码时,这个代码的话看了就想打人,未来新增一种弹窗类型的话,我们需要到 getMainData 内部去补一个 else if,一不小心可能就会影响到原有的逻辑,并且随着迭代函数会越来越大。但其实每种弹窗是相互独立的,我们并不关心其他弹窗的逻辑。
此时,就需要策略模式了。
二、策略模式是什么?
1.定义:策略模式作为一种软件设计模式 (opens new window),指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。
策略模式:
- 定义了一族算法(业务规则);
- 封装了每个算法;
- 这族的算法可互换代替(interchangeable)
2.运用:借助策略模式的思想,我们可以尝试这样写:
const strategies = {FirstStrategy() {console.log("Called FirstStrategy");},SecondStrategy() {console.log("Called SecondStrategy");},ThirdStrategy() {console.log("Called ThirdStrategy");}
}const execute = (strategy) => {return strategies[strategy]();
}execute('FirstStrategy')
execute('SecondStrategy')
execute('ThirdStrategy')
将不同的处理逻辑都放到strategies这个对象里面去统一维护,然后通过给execute()这个方法传递不同的strategy参数,然后通过统一的strategies[strategy]()去根据参数匹配不同的处理逻辑。
三、提炼优化
当我们要处理的情况较多时,如果将所有的代码都写到一个文件中,看上去还是会有些臃肿,这个时候我们就要考虑是否可以将业务代码与逻辑处理代码分离开来,于是就有了进一步的优化,如下:
1.我们可以将不同类型的处理逻辑代码全都拿到一个单独的文件当中,然后给出一个统一的函数去供业务使用:
const popTypes = {[STYLE_TYPE.Reward]: function() {...},[STYLE_TYPE.Waitreward]: function() {...},[STYLE_TYPE.Poster]: function() {...},[STYLE_TYPE.Activity]: function() {...},[STYLE_TYPE.Balance]: function() {...},[STYLE_TYPE.Cash]: function() {...},
}export function openPop(type){return popTypes[type]();
}
2.在我们需要的文件当中引入上面的配置文件
import { openPop } from './popTypes';
3.在拿到不同参数时再去根据参数,调用方法
async getMainData() {try {const res = await activityQuery(); // 请求后端数据openPop(res.styleType)} catch (error) {log.error(MODULENAME, '主接口异常', JSON.stringify(error));}
}
现在,我们的代码是不是看上去就非常的清晰了呢?嘿嘿~~
相关文章:
使用策略模式优化多重if/else
一、为什么需要策略模式? 作为前端程序员,我们经常会遇到这样的场景,例如 进入一个营销活动页面,会根据后端下发的不同 type ,前端页面展示不同的弹窗。 async getMainData() {try {const res await activityQuery()…...
逆强化学习
1.逆强化学习的理论框架 1.teacher的行为被定义成best 2.学习的网络有两个,actor和reward 3.每次迭代中通过比较actor与teacher的行为来更新reward function,基于新的reward function来更新actor使得actor获得的reward最大。 loss的设计相当于一个排序问…...
postgresql新特性之Merge
postgresql新特性之Merge 创建测试表测试案例 创建测试表 create table cps.public.test(id integer primary key,balance numeric,status varchar(1));测试案例 官网介绍 merge into test t using ( select 1 id,0 balance,Y status) s on(t.id s.id) -- 当匹配上了,statu…...
【注解】注解解析与应用场景
注解解析与应用场景 1.注解解析 注解解析就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来 2.如何解析注解? 思想:要解析谁上面的注解,就应该先拿到谁(通过反射)如果要解析类…...
mysql面试题14:讲一讲MySQL中什么是全同步复制?底层实现?
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:讲一讲mysql中什么是全同步复制?底层实现? MySQL中的全同步复制(Synchronous Replication)是一种复制模式,主服务器在写操作完成后,必须等待…...
Linux驱动设备号分配与自动创建设备节点
Linux 驱动设备号 对于 Linux 系统,为了识别和管理设备,每个设备便使用一个唯一的编号来标记设备,每个注册到内核的设备都需要一个编号,这个编号就是设备号,为了细分设备号分为主设备号和次设备号。 由于 Linux 的设…...
基于MFC和OpenCV实现人脸识别
基于MFC和OpenCV实现人脸识别 文章目录 基于MFC和OpenCV实现人脸识别1. 项目说明1. 创建项目2. 启动窗口3. 登录窗口-添加窗口、从启动窗口跳转4. 启动窗口-美化按钮5. 登录窗口-美化按钮、雪花视频6. 注册窗口-美化按钮、雪花视频、从启动窗口跳转7. 注册窗口-开启摄像头8. 注…...
力扣 -- 377. 组合总和 Ⅳ
解题步骤: 参考代码: class Solution { public:int combinationSum4(vector<int>& nums, int target) {int nnums.size();vector<double> dp(target1);//初始化dp[0]1;//填表for(int i1;i<target;i){for(int j0;j<n;j){//填表if(…...
阿里云新账户什么意思?老用户、产品首购详细说明
阿里云新账户、老账号、产品首购和同人账号什么意思?阿里云账号分为云新账户、老账户、产品首购、同人账号和同一用户,阿里云官方推出的活动很多是限制账号类型的,常见的如阿里云新用户,什么是阿里云新用户?是指从未在…...
C++ YAML使用
C++工程如何使用YAML-cpp 一、前期准备工作 1、已安装minGW、cmake、make等本地工具。 2、下载YAML-cpp第三方开源代码(一定要下载最新的release版本,不然坑很多)。 3、生成YAML-cpp静态库 (1)在yaml-cpp-master下建立build文件夹; (2)在该文件夹下生成MakaFile文…...
十二、Django之模板的继承+用户列表
模板的继承 新建layout.html: {% load static %} <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><link rel"stylesheet" href"{% static plugins…...
wzsc_文件上传(条件竞争)
打开题目链接,很常见的文件上传框 经过尝试,发现上传东西后会调用upload.php,猜测文件被传到upload目录下 随便传了几个类型的文件,访问upload目录 发现.php文件以及.htaccess、.user.ini这种配置文件都没有传上去 但是通过抓包…...
unplugin-vue-components和unplugin-auto-import插件
unplugin-auto-import:自动按需引入 vue\vue-router\pinia 等的 api unplugin-vue-components:自动按需引入 第三方的组件库组件 和 我们自定义的组件 使用此类插件,不需要手动编写import {xxx} from vue这样的代码了,提升开发效…...
docker系列文章目录
docker系列专栏笔记总算完成了,平时下班比较晚,利用晚上的一些时间整理了这一系列的学习笔记。 docker系列教程包含以下几个方面: docker环境篇 介绍docker环境的搭建,已经管理平台工具(portainer)的简单使用。 docker常用命令篇…...
第80步 时间序列建模实战:GRNN回归建模
基于WIN10的64位系统演示 一、写在前面 这一期,我们使用Matlab进行GRNN模型的构建。 使用的数据如下: 采用《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrom…...
《C和指针》笔记33:指针数组
除了创建整型数组一样,也可以声明指针数组。 int *api[10];为了弄清这个复杂的声明,我们假定它是一个表达式,并对它进行求值。下标引用的优先级高于间接访问,所以在这个表达式中,首先执行下标引用。因此,a…...
C/C++字符函数和字符串函数详解————内存函数详解与模拟
个人主页:点我进入主页 专栏分类:C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.前言 2 .memcpy函数 3.memmove函…...
CAcUiDockControlBar初始位置 2023/8/19 下午3:51:18
2023/8/19 下午3:51:18 CAcUiDockControlBar初始位置 2023/8/19 下午3:52:00 CAcUiDockControlBar的初始位置是根据其在程序代码中的设置而确定的。通常情况下,它的初始位置可以通过以下几种方式进行设置: 使用Create函数:在创建CAcUiDockControlBar对象时,可以调用Cre…...
CDH6.3.2 的pyspark读取excel表格数据写入hive中的问题汇总
需求:内网通过Excel文件将数据同步到外网的CDH服务器中,将CDH中的文件数据写入hive中。 CDH版本为:6.3.2 spark版本为:2.4 python版本:2.7.5 操作系统:CentOS Linux 7 集群方式:yarn-cluster …...
2120 -- 预警系统题解
Description OiersOiers 国的预警系统是一棵树,树中有 �n 个结点,编号 1∼�1∼n,树中每条边的长度均为 11。预警系统中只有一个预警信号发射站,就是树的根结点 11 号结点,其它 �−1…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...
rm视觉学习1-自瞄部分
首先先感谢中南大学的开源,提供了很全面的思路,减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接:https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架: 代码框架结构:readme有…...
CppCon 2015 学习:REFLECTION TECHNIQUES IN C++
关于 Reflection(反射) 这个概念,总结一下: Reflection(反射)是什么? 反射是对类型的自我检查能力(Introspection) 可以查看类的成员变量、成员函数等信息。反射允许枚…...
