重构:烧脑判断大扫除

编写业务代码的时候经常会遇到判断,面对各类业务场景,你知道最优方案吗?程序员

让咱们看看基本状况:es6

初级:if else else if一把梭干就完事设计模式

中级:switch case、if else、多态、用设计模式包装数组

高深:清晰全部判断条件的边界,用解释性强且合理的方式app


给各位大佬泡上一杯82年的卡布奇诺,细细品味。函数

代码初窥

需求:判断今日上班状况,当前时间和工做进度做为条件性能

{
    period:afteroon,// 当前时间:afternoon || night
    workProgress:start,  // 工做进度: start || end
}
复制代码

if-else

if(period === 'afternoon'){
    上班
}else if(period === 'night' && workProgress !== 'end'){
    加班
}else {
    下班
}
复制代码

优势: if else 最为常见,是全部程序员最熟悉判断语句,能够包含复杂条件。ui

缺点: 逻辑过多就会变得很是冗长难以理解。spa

若是不看上班和加班的表达式能快速理解什么状态对应的下班吗设计

switch-case

switch(period){
    case 'afternoon':
       上班
    break;
    case 'night' && workProgress:
       下班
    break;
    case  'night' && workProgress !== 'end':
       加班
    break;
    default:
       肝就完事
    break;
}
复制代码

优势: 多种平行条件下更加简洁直观,可跳出,性能更优。

缺点: 同条件的逻辑过多就会变得像裹脚布,嵌套以及非同条件的表达式难度大。

条件变得复杂,再加一个状态(星期,周2、周四固定加班),还能维护吗

三元运算: 、短路运算 && ||

优势: 代码更加的简洁精炼

缺点: 过于复杂的三元运算语义化不强同时难以维护

period === 'afternoon'? '上班' : (workProgress === 'end'? '下班' : '加班')
复制代码

同上,条件变得复杂还能维护吗,同时看懂这串代码已经须要一点时间了。。。

策略模式/状态模式 设计模式封装

优势: 易于维护,具备必定解释性,多态

缺点: 代码量复杂度增长,须要必定抽象能力

const AllState = {
    '上班':onWork,
    '下班':endWork,
    '加班':stillWork,
}
const period = 'night';
const workProgress  = 'start';
 
function onWork() {
    return period === 'afternoon';
}

 function endWork() {
    return period === 'night' && workProgress === 'end';
}

 function stillWork() {
    return period === 'night' && workProgress === 'start';
}

function getWorkState() {
    let state = '肝就对了';
    Object.keys(AllState).some((result) =>{
        if(AllState[result]()){
            state = result;
            return true;
        };
    });
    console.log(state);
    return state;
}

const workState = getWorkState();
复制代码

增长了代码可维护性和可读性,支持多态,可是也增长了代码量和时间成本

语义化

你是一个新入职的员工,你的老大拍拍你的肩膀告诉你这是前面3个离职员工留下的代码

if(state === 1){
    // 一gi窝里giaogiao
}else if(state === 2){
    // 左边画个龙右边写个bug
}else if(state === 3){
    //do something
}
.....以此类推
复制代码

新人快速成长秘笈,那就是写没有接口文档,没有需求原型的项目,里面充斥着这样的数字状态的项目

以对象取代判断条件

const stateType = {
    start: 1,  // 开始 
    doing: 2,  // 进行中
    end: 3,    // 结束
}

if(state === stateType['start']){
    //  一gigiaogiao里giaogiao
}else if(state === stateType['doing']){
    // 左边画个龙右边写个bug
}else if(state === stateType['end']){
    // do something
}
复制代码

不要以为多了一个对象代码就变冗余了,这个对象中的key正是维护这份代码最好的注释

以函数取代判断条件

以一个电商活动节日为例,要求18岁以上,女生优惠比男生优惠力度大

if(sex==='feMale' && age>18) {
    charge = (quantity * count) - 800; // 男生优惠800元
}else{
    charge = (quantity * count)*0.8 - 500; // 女生8折再优惠500元
}
复制代码
分解条件的方式改造

1.函数取代判断条件

function allowAge(){
    return sex==='feMale' && age>18;
}
复制代码

2.分解执行函数

function  maleCharge(){
    return (quantity * count) - 800;
}

 function  femaleCharge(){
    return (quantity * count)*0.8 - 500;
}
复制代码

3.缩成简单三元

charge = allowAge() ? femaleCharge() : maleCharge();
复制代码

执行语句都被封装起来且变得简短易懂

骚操做

1.若是有不执行的条件,为了减小没必要要的代码提早return

function allowAge(age){
     if (age<'18') throw new Error('No adult!');
     // 正常
}
复制代码

2.给参数设置默认值,这样就不须要作undefined类型处理和提早return了

function  maleCharge(count=5){ 
    // if (count<5) return false;
    return (quantity * count) - 800;
}
复制代码

3.将多个简单条件放在数组对象里使用includes

if(fruit === 'apple'||fruit === 'banana'||fruit === 'lemon') eatFruit()

if(['apple','banana','lemon'].includes(fruit)) eatFruits()
复制代码

4.当状态比较多的时候能够用这种方式来包装

es6中的Map容许使用对象来做为key

const worklist = () => { 
    return new Map([
      [{period:'morning',workProgress:'start'},()=>{/* 上班 */}],
      [{period:'afternoon',workProgress:'end'},()=>{/* 上班 */}],
      [{period:'night',workProgress:'doing'},()=>{/* 加班 */}],
      [{period:'night',workProgress:'start'},()=>{/* 加班 */}],
      [{period:'night',workProgress:'end'},()=>{/* 下班 */}],
      //...
    ])
}
复制代码

利用对象作为key能够存储多个数据(条件)

function getWorkState (){
  const todayWorkState = [...worklist()].filter(([key])=>(key.period == period && key.workProgress == workProgress));
  return todayWorkState[0][1];
}

const workState = getWorkState ();
复制代码

若是你看完以后满脑子的加班上班,那说明你看懂了!

若是以为不错,请素质四连,点赞、关注、转发、评论,毕竟要恰饭的嘛

相关文章
相关标签/搜索