写点什么

专栏:代码之丑(三)——switch 陷阱

  • 2010-11-24
  • 本文字数:1192 字

    阅读完需:约 4 分钟

又见 switch:

复制代码
switch(firstChar) {
case ‘N’:
nextFirstChar = ‘O’;
break;
case ‘O’:
nextFirstChar = ‘P’;
break;
case ‘P’:
nextFirstChar = ‘Q’;
break;
case ‘Q’:
nextFirstChar = ‘R’;
break;
case ‘R’:
nextFirstChar = ‘S’;
break;
case ‘S’:
nextFirstChar = ‘T’;
break;
case ‘T’:
throw new IllegalArgument();
default:
}

出于多年编程养成的条件反射,我对于 switch 总会给予更多的关照。在那本大名鼎鼎《重构》里,Martin Fowler 专门把 switch 语句单独拿出来作为一种坏味道来讨论。研习面向对象编程之后,看见 switch,我就会联想到多态,遗憾的是,这段代码和多态没什么关系。仔细阅读这段代码,我找出了其中的规律,nextFirstChar 就是 firstChar 的下一个字符。于是,我改写了这段代码:

复制代码
switch(firstChar) {
case ‘N’:
case ‘O’:
case ‘P’:
case ‘Q’:
case ‘R’:
nextFirstChar = firstChar + 1;
break;
case ‘T’:
throw new IllegalArgument();
default:
}

现在,至少看起来,这段代码已经比原来短了不少。当然这么做基于一个前提,就是这些字母编码的顺序确确实实是连续的。从理论上说,开始那段代码适用性更强。但在实际开发中,我们碰到字母不连续编码的概率趋近于 0。

但这段代码究竟是如何产生的呢?我开始研读上下文,原来这段代码是用当前 ID 产生下一个 ID 的,比如当前是 N0000,下一个就是 N0001。如果数字满了,就改变字母,比如当前 ID 是 R9999,下一个就是 T0000。在这里,字母也就相当于一位数字,根据情况进行进位,所以有了这段代码。

代码上的注释告诉我,字母的序列只有从 N 到 T,根据这个提示,我再次改写了这段代码:

复制代码
if (firstChar >= ‘N’ && firstChar <= ‘S”) {
nextFirstChar = firstChar + 1;
} else {
throw new IllegalArgument();
}

这里统一处理了字母为 T 和 default 的情形,严格说来,这和原有代码并不完全等价。但这是了解了需求后做出的决定,换句话说,原有代码在这里的处理中存在漏洞。

修改这段代码,只是运用了非常简单的编程技巧。遗憾的是,即便如此简单的编程技巧,也不是所有开发人员都驾轻就熟的,很多人更习惯于“平铺直叙”。 这种直白造就了代码中的许多鸿篇巨制。我听过不少“编程是体力活”的抱怨,不过,能把写程序干成体力活,也着实不值得同情。写程序,不动脑子,不体力才怪。

无论何时何地,只要 switch 出现在眼前,请提高警惕,那里多半有坑。

作者简介:

郑晔,ThoughtWorks 公司咨询师,拥有多年企业级软件开发经验,热衷于探索各种程序设计语言在真实软件开发中所能发挥的威力,致力于探寻合理的软件开发方式,加入 ThoughtWorks 公司后,投入到敏捷开发方法的实践之中,为其他公司提供敏捷开发方法方面的咨询服务。他的 blog 是梦想风暴

查看原文:代码之丑(三)

2010-11-24 17:557536
用户头像

发布了 22 篇内容, 共 14.7 次阅读, 收获喜欢 49 次。

关注

评论

发布
暂无评论
发现更多内容

2023年AI十大展望:GPT-4领衔大模型变革,谷歌拉响警报,训练数据告急

OneFlow

人工智能 深度学习

累计装机超过300万套 欧拉操作系统跨越生态拐点

极客天地

直播 | StarRocks 联合腾讯云分享 EMR-StarRocks 的降本增效之路

StarRocks

数据库

1月10日 KaiwuDB 1.0 线上发布会

KaiwuDB

硅基仿生业务全面 Serverless 容器化,14万+问答库助力糖尿病科普

阿里巴巴云原生

阿里云 Serverless 云原生

EMQ携“云边协同IIoT解决方案”亮相2022世界工业互联网产业大会

EMQ映云科技

人工智能 物联网 IoT 云边协同 企业号 1 月 PK 榜

强强联手 | 尚硅谷&腾讯云EMR离线数仓教程发布

小谷哥

划重点,2023 年最值得关注的 8 大技术趋势

PreMaint

人工智能 云计算 5G 技术趋势 元宇宙

Apache Tomcat 存在 JsonErrorReportValve 注入漏洞(CVE-2022-45143)

墨菲安全

安全漏洞 CVE

金融数字化为何需要低代码开发平台

力软低代码开发平台

为什么说 数据服务是数据中台的标配?

用友BIP

Hands on HTML & CSS

无人之路

CSS html

一文了解华为FusionInsight MRS HBase的集群隔离方案RSGroup

华为云开发者联盟

大数据 后端 华为云 企业号 1 月 PK 榜

YMatrix v5.0 发布:138 项深度优化,重塑集群架构,实现性能及高可用性全方位提升!

YMatrix 超融合数据库

OLAP OLTP 超融合数据库 数据库架构设计 YMatrix

IM通讯协议专题学习(七):手把手教你如何在NodeJS中从零使用Protobuf

JackJiang

即时通讯 protobuf im开发

站酷基于服务网格ASM的生产实践

阿里巴巴云原生

阿里云 云原生 服务网格

重磅发布丨从云原生到Serverless,先行一步看见更大的技术想象力

阿里巴巴云原生

阿里云 Serverless 云原生

IoT物联网设备「固件升级」OTA,「资源包更新」最佳实践——实践类

阿里云AIoT

运维 物联网 数据格式

安畅SmartOps混合云平台架构的演进之道

安畅Anchnet

云原生

喜讯!云起无垠获评《2022年度十大新锐企业》

云起无垠

Fuzzing 2022年度十大新锐企业

基于开源体系的云原生微服务治理实践与探索

阿里巴巴云原生

阿里云 开源 云原生 service mesh

从 Nginx Ingress 窥探云原生网关选型

阿里巴巴云原生

阿里云 微服务 云原生

Apache RocketMQ 斩获 InfoQ 2022 年度十大开源新锐项目

阿里巴巴云原生

阿里云 云原生 Apache RocketMQ

2023 年openEuler 社区技术委员会增选,新增2位委员

openEuler

Linux 开源 操作系统 openEuler 资讯

IoT物联网平台「设备影子」开发实战——实践类

阿里云AIoT

JavaScript json 物联网 API 储存

云渲染市场安全吗?如何保证数据安全、财产安全?

Renderbus瑞云渲染农场

云渲染 云渲染农场 云渲染安全

专栏:代码之丑(三)——switch陷阱_Java_郑晔_InfoQ精选文章