写点什么

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

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

关注

评论

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

人社部公布“数据库运行管理员”成新职业,OceanBase参与制定职业标准

OceanBase 数据库

三、HikariCP源码分析之获取连接流程三

阿白

数据库 源码解析 HikariCP 源代码 连接池

五、HikariCP源码分析之初始化分析二

阿白

数据库 源码解析 HikariCP 源代码 连接池

六、HikariConfig配置解析

阿白

数据库 源码解析 HikariCP 源代码 连接池

八、HikariCP源码分析之ConcurrentBag一

阿白

数据库 源码解析 HikariCP 源代码 连接池

十一、HikariCP源码分析之HouseKeeper

阿白

数据库 源码解析 HikariCP 源代码 连接池

新型LaaS协议Elephant Swap给ePLATO提供可持续溢价空间

BlockChain先知

2022中国物流产业大会暨企业家高峰论坛在杭州举办!

联营汇聚

SpringBoot实现异步任务Async及异步任务实现发送邮件

宁在春

springboot 异步 7月月更 邮件发送

七、HikariConfig初始化分析

阿白

数据库 源码解析 HikariCP 源代码 连接池

九、HikariCP源码分析之ConcurrentBag二

阿白

数据库 源码解析 HikariCP 源代码 连接池

资源集合

贾献华

7月月更

怎么实现您的个人知识库?

Geek_da0866

推荐 7 个学习 Web3 的开源资源

devpoint

blockchain Solidity web3 7月月更

设计消息队列存储消息的MySQL表格

joak

SQL 改写系列七:谓词移动

OceanBase 数据库

面向大数据存算分离场景的数据湖加速方案

Baidu AICLOUD

数据湖 对象存储 元数据 存算分离 层级namespace

7 行代码搞崩溃 B 站,原因令人唏嘘!

Python猫

高性能数据访问中间件 OBProxy(三):问题排查和服务运维

OceanBase 数据库

四、HikariCP源码分析之初始化分析一

阿白

数据库 源码解析 HikariCP 源代码 连接池

MIT TR50榜单公布 《麻省理工科技评论》评价毫末智行是AI自动驾驶界的颠覆势能

科技大数据

智能车

纯css实现:单行文本的打字机动画效果

南极一块修炼千年的大冰块

7月月更

一、HikariCP源码分析之获取连接流程一

阿白

数据库 源码解析 HikariCP 源代码 连接池

知识库对企业的意义

Baklib

leetcode122. Best Time to Buy and Sell Stock II 买卖股票的最佳时机 II(简单)

okokabcd

LeetCode 数据结构与算法 贪心算法

数据安全建设

奔向架构师

数据资产 7月月更

互联网基石:TCP/IP四层模型,由浅入深直击原理!

wljslmz

计算机网络 TCP/IP 网络技术 OSI模型 签约计划第三季

Serverless实战——2分钟,教你用Serverless每天给女朋友自动发土味情话

Serverless Devs

#Serverless

不要再用if-else!

Jackpop

经验分享|编写简单易用的在线产品手册小妙招

Baklib

二、HikariCP源码分析之获取连接流程二

阿白

数据库 源码解析 HikariCP 源代码 连接池

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