写点什么

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

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

关注

评论

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

【性能测试工具lmbench】快来测测你的系统可以打几分

优麒麟

Linux 开源 系统管理 优麒麟

关于黑帕云用户迁移明道云的详细说明

明道云

大数据,不只“懂数”,更要“懂行”

鼎道智联

大数据

网络安全 Kali web安全 基于SMB协议收集信息

学神来啦

Linux 运维 网络安全 WEB安全 kali Linux

华为云企业级Redis揭秘第17期:集群搭载多DB,多租隔离更降本

华为云数据库小助手

GaussDB GaussDB ( for Redis )

校招项目应该如何准备才能高大上一点

宇宙之一粟

项目 3月月更

谷歌云对象存储攻防

火线安全

安全攻防 对象存储 云安全

Tapdata加入PolarDB开源数据库社区

阿里云数据库开源

数据库 阿里云 开源 开源数据库 polarDB

阿里本地生活端智能架构设计与技术探索

阿里巴巴终端技术

端智能

新思科技加速安全软件开发,推出Code Sight插件标准版

InfoQ_434670063458

软件开发 新思科技 可信软件 IDE环境 Code Sight

架构实战营 第6期 模块一课后作业

火钳刘明

#架构实战营 「架构实战营」

Apache Flink 在国有大型银行智能运营场景下的应用

Apache Flink

大数据 flink 编程 流计算 实时计算

OpenMLDB 在线模块架构解析

第四范式开发者社区

人工智能 机器学习 数据库 开源 特征平台

实现简易的 Vue 响应式

CRMEB

19 条有效的跨端 cpp 开发经验

阿里巴巴终端技术

cpp 跨端开发

创业圈的哈利波特们注意了!霍格沃兹即将开学,谁是你的魔法导师?

创业邦

直播预告 | PolarDB-X 动手实践系列——用 PolarDB-X + Flink 搭建实时数据大屏

阿里云数据库开源

数据库 阿里云 开源 分布式 polarDB

3步排查,3步优化,探针性能损耗直降44%

TakinTalks稳定性社区

Java 性能分析 探针 性能提升 性能损耗

Go性能优化小技巧

jinjin

Go 性能优化

3大能力升级,云效+钉钉,让研发协作更「敏捷」

阿里云云效

云计算 阿里云 云原生 钉钉 敏捷研发

配置Mountebank环境-mountebank系列(2)

Bruce Talk

技术 敏捷 Agile

模块一作业

HZ

架构实战营

2022年作为一个中年程序员写给35岁的自己

Linux服务器开发

c++ 程序员 架构师 Linux服务器开发 Linux后台开发

XSS跨站脚本攻击漏洞修复技巧

喀拉峻

网络安全

英特尔X钉钉:以智能协作驱动数字办公发展

科技新消息

巧用对象存储回源绕过SSRF限制

火线安全

Web 云安全 web漏洞

Go Data Structures: Interfaces [中译]

hyx

源码 Go 语言

【Zeekr_Tech】TARA攻击树分析方法论

Zeekr_Tech

信息安全 极氪

电阻电路的等效变换(Ⅰ)

謓泽

3月月更

我们如何建立一套无参考视频质量评价体系?

声网

视频 Dev for Dev VQA

5G区块链技术让建水紫陶有了“身份证”

CECBC

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