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

if-else判断语句过多如何处理?

时间:2023-03-13 13:49:42 科技观察

1。简介我们平时写代码的时候,基本上少不了if-else判断语句。当我们的判断语句只有一层或两层时,像下面这样,情况还好,基本可以接受;if(condition){doSomeThing();}else{doSomeThing();}但是当if-else过度使用时,它会对代码的可读性和可扩展性产生负面影响,比如下面的!if(condition1){if(condition2){if(condition3){if(condition4){if(condition5){if(condition6){doSomeThing();}}}}}}如果判断语句越来越多,项目后面进行维护也会比较困难,对于后面接手项目的人来说会很头疼。因此,如何去掉代码中过多的if...else语句,体现了程序员综合运用软件重构、设计模式、面向对象设计、架构模式、数据结构等各种技术的能力。那么问题来了,如何解决代码中过多的if...else语句呢?一起来聊聊几种行之有效的解决方法吧!2.解决方案首先,我们写一个简单的程序计算器,代码如下!publicintcalculate(inta,intb,Stringoperator){intresult=Integer.MIN_VALUE;if("add".equals(operator)){结果=a+b;}elseif("multiply".equals(operator)){result=a*b;}elseif("divide".equals(operator)){result=a/b;}elseif("subtract".equals(operator)){result=a-b;returnresult;}以上是一个案例,我们来看看几种改造的方法吧!2.1、适时return如果if中的条件判断比较单一且互斥,我们可以在合适的位置直接return,废除else代码,例如改造成如下方式:publicintcalculate(inta,intb,字符串运算符){if("add".equals(operator)){returna+b;}if("subtract".equals(operator)){returna-b;}if("multiply".equals(operator)){returna*b;}if("divide".equals(operator)){returna/b;}return0;}代码是不是瞬间变得清晰了许多?2.2.引入策略模式进行转换,但是当if判断逻辑内容非常复杂时,上述方案不够优雅。这时候我们可以把if判断逻辑单独放到类中单独处理,操作方法如下!第一的,我们定义一个Operation接口用于逻辑计算publicinterfaceOperation{/***Executecalculations*@parama*@paramb*@return*/intexecute(inta,intb);}接下来是四个if判断逻辑独立成模块处理publicclassAddOperationimplementsOperation{@Overridepublicintexecute(inta,intb){returna+b;}}publicclassSubOperationimplementsOperation{@Overridepublicintexecute(inta,intb){returna-b;}}publicclassMultiOperationimplementsOperation{@Overridepublicintexecute(inta,intb){returna*b;}}publicclassDivOperationimplementsOperation{@Overridepublicintexecute(inta,intb){returna/b;}}然后,创建一个工厂类,用于处理客户端传入的参数publicclassOperatorFactory{privatestaticMapoperationMap=newHashMap<>();static{//初始化实现类operationMap.put("add",newAddOperation());operationMap.put("sub",newSubOperation());operationMap.put("multi",newMultiOperation());operationMap.put("div",newDivOperation());//更多操作符}/***获取对应的目标实现类*@paramoperator*@return*/publicstaticOptionalgetOperation(Stringoperator){returnOptional.ofNullable(operationMap.get(operator));}}最后,只在需要的地方介绍方法!publicclassOperatorTestMain{publicstaticvoidmain(String[]args){//获取计算的目标实现类OperationtargetOperation=OperatorFactory.getOperation("add").orElseThrow(()->newIllegalArgumentException("InvalidOperator"));intresult=targetOperation.execute(1,2);System.out.println("结果:"+结果);}}至此,if...else方法已经改造完毕!2.3.引入规则引擎模式进行改造。当方法内部的if...else越来越多的时候,我们可以使用规则引擎的方式来消除这种复杂性。具体做法如下!首先创建一个规则标准接口Rule,并将条件判断方法抽象出来publicinterfaceRule{/***检查是否进入规则计算*@paramexpression*@return*/booleanevalu吃了(表情表情);/***执行规则计算*@paramexpression*@return*/intexecute(Expressionexpression);}publicclassExpression{privateIntegera;私有整数b;/***计算类型*/privateStringoperator;publicExpression(Integera,Integerb,Stringoperator){this.a=a;这个.b=b;this.operator=运算符;}}接下来根据每条规则创建不同的计算实现类,以AddRule为例{返回真;}返回假;}@Overridepublicintexecute(Expressionexpression){intresult=expression.getA()+expression.getB();;返回结果;}}然后,创建逻辑处理的规则引擎publicclassRuleEngine{privatestaticListrules=newArrayList<>();静态{规则。添加(新添加规则());//添加其他规则计算实现类}/***执行规则计算*@paramexpression*@return*/publicintprocess(Expressionexpression){Rulerule=rules.stream().filter(r->r.evaluate(expression)).findFirst().orElseThrow(()->newIllegalArgumentException("ExpressiondoesnotmatchesanyRule"));返回规则。执行(表达式);}}最后,在需要的地方引入方法!publicclassRuleEngineTestMain{publicstaticvoidmain(String[]args){Expressionexpression=newExpression(1,2,"add");RuleEngine引擎=newRuleEngine();intresult=engine.process(表达式);System.out.println("结果:"+result);}}规则引擎和策略模式最大的区别在于条件逻辑判断被抽象出来,由具体的实现类来判断是否满足要求。如果满足要求,执行;否则不执行!3、可能有同学对Spring集成应用有疑问。以上介绍均为原生处理方式。在现在到处集成Spring框架的项目中,我们应该如何使用呢?我们以上面提到的《引入策略模式进行改造》为例,如果是在Spring中,我们应该如何应用呢?3.1、SpringStrategy模式实现介绍(方案一)首先,我们还是定义一个Command接口,进行方法抽象,统一公共接口eCommand{/***命令类型*@return*/StringoperateType();/***执行*@parama*@paramb*@return*/Integerexecute(inta,intb);}接着,编写四套不同的计算处理通讯@ComponentpublicclassAddCommandimplementsCommand{@OverridepublicStringoperateType(){返回“添加”;}@OverridepublicIntegerexecute(inta,intb){returna+b;}}@ComponentpublicclassSubCommandimplementsCommand{@OverridepublicStringoperateType(){return"subtract";}@OverridepublicIntegerexecute(inta,intb){returna-b;}}@ComponentpublicclassMultiCommandimplementsCommand{@OverridepublicStringoperateType(){return"multiply";}@OverridepublicIntegerexecute(inta,intb){returna*b;}}@ComponentpublicclassDivCommandimplementsCommand{@OverridepublicStringoperateType(){return"divide";}@OverridepublicIntegerexecute(inta,intb){returna/b;}}然后,写一个类似于上面的策略处理类@ComponentpublicclassCalculatorServiceimplementsApplicationContextAware{privateMapcommandMap=newConcurrentHashMap<>();/***执行计算*@paramoperateType*@parama*@paramb*@return*/publicintcalculate(StringoperateType,inta,intb){CommandtargetCommand=Optional.ofNullable(commandMap.get(operateType)).orElseThrow(()->newIllegalArgumentException("无效运算符"));返回targetCommand.execute(a,b);}@OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{MaptempMap=applicationContext.getBeansOfType(Command.class);tempMap.values().forEach(source->commandMap.put(source.operateType(),source));}}最后,我们只需要应用就是了!@RunWith(小号pringRunner.class)@SpringBootTestpublicclassCalculatorServiceTest{@AutowiredprivateCalculatorServicecalculatorService;@Testpublicvoidtest(){intresult=calculatorService.calculate("add",1,2);System.out.println("结果:"+结果);}}3.2、Spring策略模式的实现介绍(方案二,推荐)查看Spring的ioc容器,你会发现一个秘密,当一个接口有多个实现类时,Spring会自动将Strategy接口的实现类注入进去这个Map,key是beanid,value是对应的策略实现类简单的说,我们只需要通过@Autowired注入对象,不需要通过CalculatorService类单独配置。操作方法如下!首先写一个CommandFactory工厂类进行逻辑处理@ComponentpublicclassCommandFactory{/***Spring会自动将Strategy接口的实现类注入到这个Map中,key是beanid,value是对应的strategy实现class*/@AutowiredprivateMapcommandMap;/***执行计算*@paramoperateType*@parama*@paramb*@return*/publicintcalculate(StringoperateType,inta,intb){CommandtargetCommand=Optional.ofNullable(commandMap.get(operateType)).orElseThrow(()->newIllegalArgumentException("无效运算符"));返回targetCommand.execute(a,b);}}最后在合适的地方直接使用CommandFactory!@RunWith(SpringRunner.class)@SpringBootTestpublicclassCalculatorServiceTest{@AutowiredprivateCommandFactorycommandFactory;@Testpublicvoidtest(){intresult=commandFactory.calculate("addCommand",1,2);System.out.println("结果:"+结果);}}4.总结本文主要围绕如何解决if...else...问题太多做一些总结和案例分享,希望对大家有所帮助!5.参考1,baeldungjava-replace-if-statements2,知乎-如何去除代码中过多的if语句