QCon北京「鸿蒙专场」火热来袭!即刻报名,与创新同行~ 了解详情
写点什么

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

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

关注

评论

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

大数据技术发展(三):Spark 代替 Hadoop ? Spark Or Flink ?

cristal

Java 大数据 flink hadoop spark

Flink的2种部署模式-2

小知识点

scala 大数据 flink

联邦学习初识

soolaugust

学习

【Elasticsearch 技术分享】—— Elasticsearch ?倒排索引?这都是什么?

程序员小航

elasticsearch ELK 倒排索引 ES 技术分享

3 分钟生成一个单元测试报告,这个样式爱了

程序员小富

Java 测试

a站、b站、c站、d站、e站、f站、g站、h站、i站、j站、k站、l站、m站、n站…z站?

程序员生活志

对于结果不同程度的追求,决定了这个人的身价

非著名程序员

程序员 个人成长 思维模型 结果思维

终于可以职业规划了么?

escray

学习 面试

Week 11命题作业

Jeremy

我是合适的人选么?

escray

学习 面试

我以后去做什么,技术还是业务?

escray

学习 面试 职业规划

Docker 的前世今生

哈喽沃德先生

Docker 容器 微服务 虚拟化

SpreadJS 应用案例:电力自动化在线数据采集报表系统

葡萄城技术团队

SpreadJS 电力 报表

再见C++

Sunny.

c++ 踩坑

简单交互式页面的思考(C)

Alex

指针 C语言 交互设计

公司想要大龄程序员么?

escray

学习 面试

如何通过技术面试?

escray

学习 面试

究竟要找什么样的工作?

escray

学习 面试

我喜欢的工作,喜欢我么?

escray

学习 面试

一看就懂的三次握手

书旅

TCP 三次握手 操作系统 协议族

性能全开的十代酷睿,造就惠普光影精灵 6 的电竞燃魂

最新动态

星火PLUS交易所打造无边界数字经济联盟,掀起币圈追捧热潮

InfoQ_967a83c6d0d7

搞一搞Elasticsearch

北漂码农有话说

MySQL系列(一):MySQL深入学习先导篇之基础架构

z小赵

MySQL 数据库

一文读懂jar包的小秘密

程序那些事

Java jar jar包的小秘密 java解密

Centos7下service配置知识

Week 11 学习总结

Jeremy

【API进阶之路】逆袭!用关键词抽取API搞定用户需求洞察

华为云开发者联盟

接口 软件开发 API 华为云 API Explorer平台

四十不惑,准备面试

escray

学习 面试

如何使 Grafana as code

郭旭东

翻译 Grafana

一个@Transaction哪里来这么多坑?

程序员DMZ

spring 事务 读写分离

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