写点什么

专栏:代码之丑(三)——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:557367
用户头像

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

关注

评论

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

云端的 ABAP Restful 服务开发以及通过 abapGit 传输到其他系统的详细步骤

汪子熙

git SAP abap 5月月更 abapgit

确保 Kubernetes 安全合规的 6 个最佳实践

Rancher

Kubernetes k8s rancher

【直播回顾】Hello HarmonyOS进阶课程第四课——ArkUI动画开发

HarmonyOS开发者

HarmonyOS

Linux环境显式使用动态库

Loken

音视频 5月月更

刷新三项世界纪录!浪潮云ICP ARM架构获SPEC Cloud测试全球第一名

云计算

数据指标体系如何搭建才最有效,从0到1带你快速入门丨02期直播回顾

袋鼠云数栈

当前中小企业网络营销缺少的三个方面

源字节1号

前端开发 后端开发 小程序开发 网站开发

全栈、云原生的数据分析时代已来,我们如何抓住机会?

亚马逊云科技 (Amazon Web Services)

数据分析 云原生 全栈

建站建设必备的资料是什么?

源字节1号

软件开发

一款免费的排队叫号工具,居然有这么多功能,赶紧收藏起来!

天天预约

小程序 SaaS 工具分享 排队

Flutter的特别之处

Geek_99967b

flutter 小程序开发

打码打码Python爬虫,某省建筑市场请求地址参数分析,手慢无爬虫

梦想橡皮擦

5月月更

大咖说|Kubernetes自动伸缩实现方式深度讲解

云智慧AIOps社区

云计算 微服务 云原生 #Kubernetes#

案例成果展 | 灵雀云助力中国人民银行清算总中心构建裸金属容器平台

York

灵雀云 容器 微服务 云原生

什么是知识管理?知识管理的方法?

小炮

Docker下RabbitMQ四部曲之一:极速体验(单机和集群)

程序员欣宸

Java RabbitMQ 5月月更

Kubernetes Gateway API - 服务网络的演进

Flomesh

Kubernetes Gateway ingress

云原生数据库的下一次变革发生在哪里?

亚马逊云科技 (Amazon Web Services)

数据库 云原生

企业上云,安全合规如何进阶 ——一文拆解亚马逊云科技云安全理念与实践

亚马逊云科技 (Amazon Web Services)

云安全 亚马逊云

【高并发】优化加锁方式时竟然死锁了!!

冰河

并发编程 多线程 高并发 协程 异步编程

Yii2文件/图片上传实例

Owen Zhang

php

5G 时代,我们需要更便捷的RTC技术服务

曲多多(嗨翻屋)版权音乐

RTC 音乐

【LeetCode】房屋偷盗Java题解

Albert

LeetCode 5月月更

怎样让智能电视更加智能

Geek_99967b

小程序 小程序容器 智能电视

开源生态|打造活力开源社区,共建开源新生态!

Orillusion

开源 WebGL 元宇宙 Metaverse webgpu

JVM进阶(十九)——Class文件常量池

No Silver Bullet

JVM class 5月月更

IM即时通讯为企业业务移动化带来了怎样的便利?

BeeWorks

web前端培训 | 代码如何配置规范并格式化

@零度

前端开发

什么是小程序运行时框架?

Geek_99967b

native 小程序容器 小程序开发

面试突击51:为什么单例一定要加 volatile?

王磊

Java 面试

得物技术Filament Creator材质编辑工具的实现

得物技术

模型 3D模型 3D 渲染 引擎

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