如何优化代码中大量的if/else,switch/case?
yuyutoo 2024-10-14 16:16 2 浏览 0 评论
前言
随着项目的迭代,代码中存在的分支判断可能会越来越多,当里面涉及到的逻辑比较复杂或者分支数量实在是多的难以维护的时候,我们就要考虑下,有办法能让这些代码变得更优雅吗?
正文
使用枚举
这里我们简单的定义一个表示状态的枚举。
public enum Status { NEW(0),RUNNABLE(1),RUNNING(2),BLOCKED(3),DEAD(4); public int statusCode; Status(int statusCode){ this.statusCode = statusCode; } }
那么我们在使用的时候就可以直接通过枚举调用了。
int statusCode = Status.valueOf("NEW").statusCode;
优雅的解决了下面代码赋值的方式
if(param.equals("NEW")){ statusCode = 0; }else if(param.equals("RUNNABLE")){ statusCode = 1; } ...
善用 Optional
在项目中,总少不了一些非空的判断,可能大部分人还是如下的用法
if(null == user){ //action1 }else{ //action2 }
这时候该掏出Optional这个秘密武器了,它可以让非空校验更加优雅,间接的减少if操作。没了解过Optional的同学可自行Google,这里就不再赘述。
Optional<User> userOptional = Optional.ofNullable(user); userOptional.map(action1).orElse(action2);
上面的代码跟第一段是等效的,通过一些新特性让代码更加紧凑。
表驱动法
来自Google的解释:表驱动法是一种编程模式,它的本质是,从表里查询信息来代替逻辑语句(if,case)。下面看一个案例,通过月份来获取当月的天数(仅作为案例演示,获取2月份的数据不严谨),普通做法:
int getMonthDays(int month){ switch(month){ case 1:return 31;break; case 2:return 29;break; case 3:return 31;break; case 4:return 30;break; case 5:return 31;break; case 6:return 30;break; case 7:return 31;break; case 8:return 31;break; case 9:return 30;break; case 10:return 31;break; case 11:return 30;break; case 12:return 31;break; default:return 0; } }
表驱动法实现方式
int monthDays[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int getMonthDays(int month){ return monthDays[--month]; }
其实这里的表就是数组而已,通过直接查询数组来获得需要的数据,那么同理,Map之类的容器也可以成为我们编程概念中的表。
Map<?, Function<?> action> actionsMap = new HashMap<>(); // 初试配置对应动作 actionsMap.put(value1, (someParams) -> { doAction1(someParams)}); actionsMap.put(value2, (someParams) -> { doAction2(someParams)}); actionsMap.put(value3, (someParams) -> { doAction3(someParams)}); // 省略 null 判断 actionsMap.get(param).apply(someParams);
通过Java8的lambda表达式,我们把需要执行东西存进value中,调用的时候通过匹配key的方式进行。
提前判断返回
在之前的文章《优化代码里的 “ 坏味道 ”》里也有提过,如下语句
if(condition){ //dost }else{ return ; }
改为
if(!condition){ return ; } //dost
避免一些不必要的分支,让代码更精炼。
其他方法
除了上面提到的方法,我们还可以通过一些设计模式,例如策略模式,责任链模式等来优化存在大量if,case的情况,其原理会和表驱动的模式比较相似,大家可以自己动手实现一下,例如我们在Netty的使用过程中,可能会出现需要大量判断不同的命令去执行对应动作的场景。
ServerHandler.java if(command.equals("login")){ //执行登录 }else if(command.equals("chat")){ //聊天 }else if(command.equals("broadcast")){ //广播信息 } ....
该如何处理呢?这里先卖个关子,大家可以先思考一下,笔记后续会写一些关于Netty实现IM的文章,到时候会详细介绍。
结语
最后要明确一点,不是所有的if/else,switch/case都需要优化,当我们发现有“痛点”或者“闻到代码有坏味道”再来优化才是最好的,不然你可能会写了一个从不扩展的可扩展代码,所有的优化都是为了更好的迭代项目,更好的服务于业务,而不是为了优化而优化。
欢迎工作一到五年的Java工程师朋友们加入Java程序员开发: 721575865
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
相关推荐
- 如何在HTML中使用JavaScript:从基础到高级的全面指南!
-
“这里是云端源想IT,帮你...
- 推荐9个Github上热门的CSS开源框架
-
大家好,我是Echa。...
- 硬核!知网首篇被引过万的论文讲了啥?作者什么来头?
-
整理|袁小华近日,知网首篇被引量破万的中文论文及其作者备受关注。知网中心网站数据显示,截至2021年7月23日,由华南师范大学教授温忠麟等人发表在《心理学报》2004年05期上的学术论文“中介效应检验...
- 为什么我推荐使用JSX开发Vue3_为什么用vue不用jquery
-
在很长的一段时间中,Vue官方都以简单上手作为其推广的重点。这确实给Vue带来了非常大的用户量,尤其是最追求需求开发效率,往往不那么在意工程代码质量的国内中小企业中,Vue占据的份额极速增长...
-
- 【干货】一文详解html和css,前端开发需要哪些技术?
-
网站开发简介...
-
2025-02-20 18:34 yuyutoo
- 分享几个css实用技巧_cssli
-
本篇将介绍几个css小技巧,目录如下:自定义引用标签的符号重置所有标签样式...
- 如何在浏览器中运行 .NET_怎么用浏览器运行代码
-
概述:...
- 前端-干货分享:更牛逼的CSS管理方法-层(CSS Layers)
-
使用CSS最困难的部分之一是处理CSS的权重值,它可以决定到底哪条规则会最终被应用,尤其是如果你想在Bootstrap这样的框架中覆盖其已有样式,更加显得麻烦。不过随着CSS层的引入,这一...
-
- HTML 基础标签库_html标签基本结构
-
HTML标题HTML标题(Heading)是通过-...
-
2025-02-20 18:34 yuyutoo
- 前端css面试20道常见考题_高级前端css面试题
-
1.请解释一下CSS3的flexbox(弹性盒布局模型),以及适用场景?display:flex;在父元素设置,子元素受弹性盒影响,默认排成一行,如果超出一行,按比例压缩flex:1;子元素设置...
- vue引入外部js文件并使用_vue3 引入外部js
-
要在Vue中引入外部的JavaScript文件,可以使用以下几种方法:1.使用``标签引入外部的JavaScript文件。在Vue的HTML模板中,可以直接使用``标签来引入外部的JavaScrip...
- 网页设计得懂css的规范_html+css网页设计
-
在初级的前端工作人员,刚入职的时候,可能在学习前端技术,写代码不是否那么的规范,而在工作中,命名的规范的尤为重要,它直接与你的代码质量挂钩。网上也受很多,但比较杂乱,在加上每年的命名都会发生一变化。...
- Google在Chrome中引入HTML 5.1标记
-
虽然负责制定Web标准的WorldWideWebConsortium(W3C)尚未宣布HTML5正式推荐规格,而Google已经迁移到了HTML5.1。即将发布的Chrome38将引入H...
- HTML DOM 引用( ) 对象_html中如何引用js
-
引用对象引用对象定义了一个同内联元素的HTML引用。标签定义短的引用。元素经常在引用的内容周围添加引号。HTML文档中的每一个标签,都会创建一个引用对象。...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)