当前位置: 首页 > 科技观察

【前端】重构,有味道的代码07──简化条件逻辑

时间:2023-03-12 09:31:59 科技观察

本文转载自微信公众号《前端引力》,作者一川。转载本文请联系前端Gravity公众号。简化条件逻辑简化条件逻辑常用的方法有:分解条件表达式合并条件表达式,用guard语句替换嵌套条件表达式,用多态替换条件表达式,引入特例,引入断言1.分解条件表达式在编程中,复杂条件表达式逻辑会导致算法的复杂度增加,因为会根据不同的条件分支做不同的事情,从而得到复杂冗长的函数。大家知道,函数越大越长,代码的可读性越差,越难理解和阅读。前面的文章中,大块函数可以根据功能意图分解成几个小函数,所以条件逻辑函数可以根据逻辑分支的意图进行分解。原代码:if(!have.before(plan.summerStart)&&!plan.after(plan.summerEnd)){charge=quantity*plan.summerRate;}else{charge=quantity*plan.regularRate+plan.regularServiceCharge;}重构代码:charge=summer()?summerCharge():regularCharge();functionsummer(){return!have.before(plan.summerStart())&&!have.aftet(plan.summerEnd());}functionsummerCharge(){returnquantity*plan.summerRate;}functionregularCharge(){returnquantity*plan.regularRate+plan.regularServiceCharge;}2。合并条件表达式正在执行代码条件检查。虽然检查条件不同,但处理事件的行为是一致的。与其使用条件逻辑来处理事件,不如使用逻辑“或”和“与”将它们组合成条件表达式,分解冗长的功能代码。使用条件表达式可以让代码阅读起来更清晰,函数提炼可以将条件函数的代码逻辑提炼成独立的函数,可以明确代码的含义。具体来说,在组合条件表达式时,首先要判断它们是否有副作用,查询函数和修改函数分开处理。使用适当的逻辑运算符将两个逻辑条件表达式合并为一个。原代码:if(employee.seniority<2)return0;如果(员工月数>12)返回0;如果(员工。时间)返回0;重构代码:functionfunc(){return(employee.seniority<2)||(employee.months>12)||employee.time)}if(func())return0;3、用guard语句替换嵌套的条件表达式条件表达式通常有两种风格:两个条件分支都是正常的行为,可以使用if...else...;当只有一个条件分支时,是正常行为,另一个分支是异常行为,即应该单独检查罕见的条件(这是一个“监护人声明”),条件为真立即返回从功能。所谓“守卫语句”而不是嵌套的条件表达式,就是要特别注意某个分支。实际上,条件语句并没有被一视同仁,而是依赖于最重要的分支语句,让读者在阅读代码时能够一眼看穿其中的逻辑。原代码:functionpayMount(){letresult;if(isDead){result=amountFunc();}else{if(isSeparated){result=separatedAmout();}else{if(isRetired){result=retiredAmount()}else{result=normalAmount();}}}returnresult;}重构代码:functionpayMount(){if(isDead)result=amountFunc();if(isSeparated)result=separatedAmout();if(isRetired)result=retiredAmount();returnnormalAmount();}4.用多态替换条件表达式。编程中复杂的条件逻辑很难理解。与其寻求为条件逻辑添加结构,不如将分支条件拆分为不同的场景,即高级用例。在拆解复杂的条件逻辑时,有时会发现条件逻辑本身的结构就足以表达,但是使用类和多态可以将逻辑拆分,表达得更清晰。如果现有的类不具备多态行为,可以创建一个工厂函数返回合适的对象实例,调用方法时就可以得到对象实例。如果条件逻辑没有被提炼成一个独立的函数,那么可以将带有条件的函数移到一个超类中。可选择在子类中创建一个函数,覆盖超类中包含条件表达式的函数,并将子类相关条件表达式的分支复制到新函数中进行调整。原代码:switch(user.type){case"UserName":return"yichuan";case"UserAge":returnthis.age>18?"adult":"minor";case"UserUniversity":returnthis.score>600?"985大学":"非985大学";default:return"unknown";}重构代码:classUserName{getdetail(){return"yichuan";}}classUserAge{getdetail(){returnthis.age>18?"Adult":"次要";}}classUserUniversity{getdetail(){returnthis.score>600?"985University":"Non-985University";}}5.引入特殊情况常见的重复代码是:使用一个数据结构两者都是检查一个特殊值,当这个特殊值出现时做同样的事情.如果你发现你的代码中多个地方以相同的方式处理同一个特殊值,你可以将处理逻辑组合在一起。处理重复代码的最好方法是使用“特例”模式,创建一个特例元素来处理特例的常见行为,并且可以使用函数调用来替换部分特例检查逻辑。通常,特殊情况有几种表现形式,我们可以采用常用的方法来处理。例如:只从对象中读取数据,您可以提供一个带有预填充值的文字对象。除了获取简单的值,如果需要更多的行为,可以创建保证。所有常见行为对应的函数特例对象,可以封装成一个类返回,也可以转换插入到数据结构中//原代码if(flag==="unkown")name="yichuan";//RefactoredcodeclassUser{getname(){return"yichuan";}}6.引入断言在开发程序时,代码只在某个条件为真时运行,通常的做法是使用注释来解释它。使用断言可以清楚地标记假设,因为条件表达式应该总是等于真,并且断言的失败不应该在系统的任何地方被捕获。断言具有很高的交流价值,可以解决目前正在追踪的错误,但自测试代码会降低断言在调试过程中的价值,因为逐步接近单元测试通常有助于调试。原始代码:func(num){return(discountRate)?num-(discountRate*num):num;}重构代码:setdiscountRate(num){assert(null===num||num>=0);discountRate=num;}小结本文主要介绍如何简化条件逻辑,让条件逻辑可以操作,代码也变得更清晰易懂。参考文章《重构──改善既有代码的设计(第2版)》