写点什么

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

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

关注

评论

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

异步请求积压可视化|如何 1 分钟内快速定位函数计算积压问题

Serverless Devs

计算IIS

杉数科技

求解器 优化求解器 计算IIS 混合整数规划 杉数科技

Window下Redis的安装和部署详细教程

明金同学

redis

你知道钓鱼网站的形成步骤吗?一次网络钓鱼演练带你了解(增强安全意识)

H

网络安全 钓鱼网站

网络安全:SQL 注入漏洞

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

SQL注入-“错误”的语句为什么会得到“正确”的结果?

BUG侦探

MySQL 网络安全 SQL注入

StarRocks 元数据管理及 FE 高可用机制

邸星星

BerkeleyDB-JE bdbje StarRocks元数据管理

万字通俗讲解何为复杂度

华为云开发者联盟

数据结构 时间复杂度 复杂度 空间复杂度 复杂度分许

第十五节:SpringBoot使用JPA访问数据库

入门小站

spring-boot

报名直达丨HarmonyOS开发者创新大赛线下城市交流会来了,约吗?

HarmonyOS开发者

HarmonyOS 交流 创新大赛

为什么国企要加快推进数字化转型?

用友BIP

数字化转型 用友 用友iuap 用友YonBIP 国企

学生外包管理系统架构设计文档

孙强

#架构实战营

【场景化集成方案】如何让企业快速集成钉钉各种能力

钉钉开发者

钉钉能力中心 钉钉官网 场景化能力包 场景化解决方案 应用集成方案

极速生成缩略图,Serverless 支撑赛事转播锁定冬奥亮点

Serverless Devs

JWT Token在线编码生成

入门小站

工具

手把手教学电瓶车进电梯检测、多类别车辆追踪、异常行为检测产业级应用

百度开发者中心

浅析企业云服务之SaaS、PaaS、IaaS对比分析

郑州埃文科技

IaaS PaaS SaaS

COPT4.0新增凸QP、QCP和QCQP求解能力

杉数科技

求解器 优化求解器 凸QP 凸QCP

如何使用 Apache APISIX CSRF 安全插件拦截跨站点伪造攻击

API7.ai 技术团队

CSRF API网关 Apache APISIX

新插件上线,public API 处理能力更进一步

API7.ai 技术团队

HTTP APISIX APISIX 网关

技术干货 | WebRTC ADM 源码流程分析

网易云信

音视频

如何在设计时保证RPA机器人的稳定运行?

金小K

阿里云资深专家李国强:云原生的一些趋势和新方向

Serverless Devs

常青藤开源科技加入,龙蜥社区再迎 HPC 和开源领域新伙伴

OpenAnolis小助手

Linux 开源 高性能计算

Nacos 在 Apache APISIX API 网关中的服务发现实践

API7.ai 技术团队

nacos 注册中心 服务发现 API网关 APISIX

MatrixOne 0.2.0性能测试报告

MatrixOrigin

开源 MatrixOrigin MatrixOne 超融合异构云原生数据库 矩阵起源

APP热更新技术最优解,不只是支持热更新...

Speedoooo

小程序 APP开发 容器安全 热更新 小程序容器

使用goofys挂载S3 bucket为文件系统

阿呆

文件系统 goofys aws s3

生态扩大进行中!Apache APISIX 集成 Splunk HTTP Event Collector

API7.ai 技术团队

API网关 Apache APISIX

2022写作计划2月文章排行榜

TGO鲲鹏会

TGO鲲鹏会 写作计划

斯图飞腾Stratifyd入选「2022爱分析·营销科技厂商全景报告」

极客天地

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