js程序中最常用的if else循环,如果分枝很多的的情况下难免使写出的程序又臭又长,但是根据需求又必须将这些分支处理,此时稍有经验的程序员可能会想到用switch case优化但是只是仅仅做到利于阅读,最好的方法是用策略模式进行优化。

那么如何拒绝使用if else呢?

如果程序中只有一个else:

if(con){
dosomething();
}else{
dootherthings();
}

可以用如下的方法拒绝else:

if(con){
dosomething();
return;
}
dootherthings();

或者用三目运算符:con ? dosometing() : dootherthings();

如果程序中有多个else:

if(con1){
dothing1();
}else if(con2){
dothing2();
}else if(con3){
dothing3();
}

或者像我们系统里面这样:

可以用策略树实现:

var stats ={
obj1:function(){
doSomething1();
},
obj2:function(){
doSomething2();
},
obj3:function(){
doSomething3();
},
obj4:function(){
doSomething4();
},
obj5:function(){
doSomething5();
}
}

调用:

function handle(obj){
stats[obj.name]();
}
我是这样实现的
注释部分是之前的写法,箭头部分是我优化的内容。

函数定义。

如果没有调用方法,可以用面向对象思想,用健值对实现,比switch要简单:

 

总结

使用if...else...的弊端在于:不利于对程序的扩展,如果新添加了一个颜色类型,那么就得去修改程序再添加一个if...else...分支,根据“开-闭原则”的宗旨:对扩展开,对修改闭。显然是用if...else...已经go out了。

策略模式最开始在java用的多,使用的多态机制指:方法的重构,根据方法名相同儿参数不同的机制,来实现拒绝关键字。

我们将这个概念移植到javaScript也毫不违和。

真的是在前人基础上写switch和if else要写吐了,没办法。

我们回头再来总结一下什么是策略模式,以及策略模式的优缺点:

策略模式是oop中最著名的设计模式之一,是对方法行为的抽象,可以归类为行为设计模式,也是oop(Object Oriented Programming,面向对象编程)中interface(接口,这块如果有更好的解读,欢迎评论)经典的应用。其特点简单又实用,是我最喜欢的模式之一。策略模式定义了一个拥有共同行为的算法族,每个算法都被封装起来,可以互相替换,独立于客户端而变化。

我们可以从三个方面来理解策略模式:

1.算法族
使用多种不同的处理方式,做同样的事情,仅仅是具体行为有差别。这些处理方式,组合构成算法策略族,它们的共性,体现在策略接口行为上。

2.算法封装
将各个算法封装到不同的类中,这样有助于客户端来选择合适的算法。

3.可互相替换
客户端可以在运行时选择使用哪个算法,而且算法可以进行替换,所以客户端依赖于策略接口。

据此,可以推断出策略模式的使用场景:

  1. 针对同一问题的多种处理方式,仅仅是具体行为有差别时;
  2. 需要安全地封装多种同一类型的操作时;
  3. 同一抽象类有多个子类,而客户端需要使用 if-else 或者 switch-case 来选择具体子类时。

策略模式的优缺点
优点

  1. 易于扩展,增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合开放封闭原则
  2. 避免使用多重条件选择语句,充分体现面向对象设计思想
  3. 策略类之间可以自由切换,由于策略类都实现同一个接口,所以使它们之间可以自由切换
  4. 每个策略类使用一个策略类,符合单一职责原则
  5. 客户端与策略算法解耦,两者都依赖于抽象策略接口,符合依赖反转原则
  6. 客户端不需要知道都有哪些策略类,符合最小知识原则

缺点

  1. 策略模式,当策略算法太多时,会造成很多的策略类
  2. 客户端不知道有哪些策略类,不能决定使用哪个策略类,这点可以考虑使用IOC容器和依赖注入的方式来解决

以上,完。最后附上我写的一个demo的代码。

import { Icon, WrapNo } from 'common';
import React, { Component, } from 'react'; export const stateList = [
{
value:"ON",
str: "已开启",
iconStr:"icon-running",
colorStr:"#52C41A"
},
{
value: "OFF",
str: "已关闭",
iconStr:"icon-power-off",
colorStr:"#909090"
},
{
value: "NOT_ALLOCATED",
str: "未部署",
iconStr:"icon-power-off",
colorStr:"#909090"
},
{
value: "LOCKED",
str: "已锁定",
iconStr:"icon-lock-circle",
colorStr:"#d36564"
},
{
value: "PAUSED",
str: "已暂停",
iconStr:"icon-pause",
colorStr:"#e0ac42"
},
{
value: "UNKNOWN",
str: "未知",
iconStr:"icon-power-off",
colorStr:"#909090"
},
{
value: "MANAGED",
str: "纳管中",
iconStr:"icon-running",
colorStr:"#52C41A"
}
] export const getStateLabel = (systemParam = [], value) => {
const result = systemParam.find(item => item.value === value)
if (result) {
return (<div><Icon color={result.colorStr} type={result.iconStr} /> {result.str}</div>)
}
return "--"
}

使用:

import {getStateLabel, stateList} from "src/utils/constant"

columns = [
{
title: '状态',
width: 160,
//align: 'center',
dataIndex: 'state',
fixed: 'left',
render: text => getStateLabel(stateList, text),
// render: text => {
// let str = '';
// let iconStr = '';
// let colorStr = '';
// switch (text) {
// case 'ON': str = '已开启'; iconStr = 'icon-running'; colorStr = '#52C41A'; break;
// case 'OFF': str = '已关闭'; iconStr = 'icon-power-off'; colorStr = '#909090'; break;
// case 'NOT_ALLOCATED': str = '未部署'; iconStr = 'icon-power-off'; colorStr = '#909090'; break;
// case 'LOCKED': str = '已锁定'; iconStr = 'icon-lock-circle'; colorStr = 'rgb(211, 101, 100)'; break;
// case 'PAUSED': str = '已暂停'; iconStr = 'icon-pause'; colorStr = 'rgb(224, 172, 66)'; break;
// case 'UNKNOWN': str = '未知'; iconStr = 'icon-power-off'; colorStr = '#909090'; break;
// }
// return (<div><Icon color={colorStr} type={iconStr} /> {str}</div>);
// }
}]

2022-9-28补充

 定义:

//处理中 已解决 未处理 挂起 关闭
//名称 颜色 状态
const status = {
2:{
name: "处理中",
color: "rgba(88, 140, 233, 1)",
backGround: "rgba(40, 173, 240, 0.1)",
},
3:{
name: "已解决",
color: "rgba(24, 182, 129, 1)",
backGround: "rgba(45, 191, 154, 0.1)",
},
1:{
name: "未处理",
color: "rgba(255, 166, 0, 1)",
backGround: "rgba(255, 164, 51, 0.1)",
},
5:{
name: "撤销",
color: "rgba(255, 87, 53, 1)",
backGround: "rgba(255, 83, 89, 0.1)",
},
6:{
name: "挂起",
color: "rgba(255, 87, 53, 1)",
backGround: "rgba(255, 83, 89, 0.1)",
},
4:{
name: "关闭",
color: "rgba(80, 87, 102, 1)",
backGround: "rgba(80, 87, 102, 0.1)",
}
}
 
使用:
  <div class="space_between status">
<div class="left">客服处理备注</div>
<div class="right"
:style="{ color: status[pageInfo.businessStatus]?.color,background:status[pageInfo.businessStatus]?.backGround}">{{status[pageInfo.businessStatus]?.name}}</div>
</div>

  必须加?status[pageInfo.businessStatus]?.color 否则报错

主要是获取数据时机,导致获取不到对象,必须加判断

JavaScript用策略模式消除if else 和 switch的更多相关文章

  1. JavaScript实现策略模式

    在开篇之前先分享今天看到的一句关于设计模式的话:将不变的部分和变化的部分隔开是每个设计模式的主题 请大家自行感受这句话的精髓所在,并且思考学习设计模式究竟能给我们编程带来什么样的东西,欢迎大家在文章下 ...

  2. javascript设计模式——策略模式

    前面的话 在程序设计中,常常遇到类似的情况,要实现某一个功能有多种方案可以选择.比如一个压缩文件的程序,既可以选择zip算法,也可以选择gzip算法.这些算法灵活多样,而且可以随意互相替换.这种解决方 ...

  3. javascript 设计模式-----策略模式

    在<javascript设计模式>中,作者并没有向我们介绍策略模式,然而它却是一种在开发中十分常见的设计模式.最常见的就是当我们遇到一个复杂的表单验证的时候,常常需要编写一大段的if和el ...

  4. [设计模式] javascript 之 策略模式

    策略模式说明 定义: 封装一系列的算法,使得他们之间可以相互替换,本模式使用算法独立于使用它的客户的变化. 说明:策略模式,是一种组织算法的模式,核心不在于算法,而在于组织一系列的算法,并且如何去使用 ...

  5. 最容易懂的策略模式消除if-else分支,实现开闭原则,提高可扩展性

    1 介绍 策略模式最常用的场景就是用于消除代码中的if-else,这里所说的if-else并不是说任何简单的判断都引入策略模式来优化,这样反而会增加代码的复杂度. 反例:使用策略模式对一个boolea ...

  6. javascript设计模式-策略模式

    策略模式笔记   将定义的一组算法封装起来,使其相互之间可以替换.   封装的算法具有一定独立性,不会随客户端变化而变化.   与状态模式异同?     1. 结构上看,它与状态模式很像,也是在内部封 ...

  7. javascript 写策略模式,商场收银打折优惠策略

    [Decode error - output not utf-8] ----------------------------- 购物清单 方便面 : 100 x 50 = 5000 | 4000 菊花 ...

  8. JavaScript设计模式 - 策略模式(表单验证)

    表单提交的时候,总是要校验,不同的表单可能校验相同的功能. 为了避免代码重复的复制黏贴,使用策略模式,写出来的代码赏心悦目,且可扩展,还可以作为插件到处使用 <!DOCTYPE html> ...

  9. JavaScript 模拟策略模式

    /** * 模拟一个接口,其方法会抛出异常: */ function FlyInter () {} FlyInter.prototype.fly = function() { throw '实现这个接 ...

  10. JavaScript设计模式之策略模式

    所谓"条条道路通罗马",在现实中,为达到某种目的往往不是只有一种方法.比如挣钱养家:可以做点小生意,可以打分工,甚至还可以是偷.抢.赌等等各种手段.在程序语言设计中,也会遇到这种类 ...

随机推荐

  1. Linux 基础(一)

    Linux 基础(一) 理念 一切皆文件 硬件 文件名 显示器 fb0 鼠标 mouse1 键盘 event0 触摸屏 event1 摄像头 video0 打开摄像头:open video0 ​​打开 ...

  2. 刷了一个月AI歌唱的视频 做一个大胆预测

    现在的AI热点转到ChatAI和AI唱歌去了 很好理解(现在每天在看Neuro的切片 感慨这才是看V的初心 可惜Neuro这个形象在创立的时候只是一个ChatAI 和游戏用的GameBOT并不是同一个 ...

  3. ROS的通信机制

    通信机制 节点--执行单元 执行具体任务的进程.独立运行的可执行文件: 不同节点可以使用不同的编程语言,可分布式运行在不同的主机上. 节点在系统中的名称是必须是唯一的. 节点管理器(ROS Maste ...

  4. Python中的弱引用与基础类型支持情况探究

    背景 最近有一个业务场景需要用Python自行实现一个简单的LRU cache,不可避免的接触到了弱引用这一概念,这里记录一下. 强引用 Python内存回收由垃圾回收器自动管理,当一个对象的引用计数 ...

  5. Cilium 系列-3-Cilium 的基本组件和重要概念

    系列文章 Cilium 系列文章 前言 安装完了,我们看看 Cilium 有哪些组件和重要概念. Cilium 组件 如上所述,安装 Cilium 时,会安装几个运行组件(有些是可选组件), 它们各是 ...

  6. Linux 脚本:shell

    # 以脚本所在目录作为脚本执行时的当前路径. -P 选项寻找物理上的地址,忽略软连接. SCRIPT_DIR=$(cd $(dirname $0); pwd -P) # 在任意位置执行自己的可执行程序 ...

  7. ChatGPT 1.0.0安卓分析,仅限国内分享

    ChatGPT 1.0.0安卓分析,仅限国内分享 博客园首发,本文将对ChatGpt Android版本1.0.0 APK进行静态解包分析和抓包分析,从ChatGpt Android APK功能的设计 ...

  8. 2022-1-10 WPF基础知识点温习

    一.window Icon :允许自定义窗口图标 ResizeMode:调整控制大小,默认为CanResize. CanMinimize允许用户最小化窗口. NoResize没有格式.  ShowIn ...

  9. 叶绿素含量测定仪SPAD-502怎么使用?

      本文介绍基于SPAD-502叶绿素仪测定植被叶片叶绿素含量的方法.   SPAD-502是由日本柯尼卡美能达(Konica Minolta)株式会社生产的轻便.手持式叶绿素仪,可以在不破坏作物的情 ...

  10. 手动安装vur-router并引用

    安装并引用 安装 npm install vue-router 引用 步骤一:在src路径下,创建router文件夹, 其下创建index.js // router/index.js import V ...