Redian新闻
>
“ 现在开始,把代码里的 ‘ else ’ 丢掉!”

“ 现在开始,把代码里的 ‘ else ’ 丢掉!”

公众号新闻

作者 | Preslav   译者 | 明明如月  出品 | CSDN(ID:CSDNnews) 

链接:https://preslav.me/2023/09/22/ditch-that-else/

这篇文章主要探讨了在编程中如何处理“正常路径”和“边缘情况”。作者指出,大多数代码库中 80% 的代码负责处理预期的“正常路径”,而剩下的 20% 负责处理错误和异常。常见的做法是使用 if-else 语句,将正常路径放在 if 块中,而边缘情况放在 else 块中。这样的做法经常导致代码复杂性增加,特别是当出现多层嵌套时问题尤为严重。作者提出了一个解决方案,即优先处理边界情况并提前返回,以减少代码的复杂性和提高可维护性。这种方法不仅可以使代码结构更清晰,还可以降低引入错误的风险。
我在职业生涯中见过的大多数代码都遵循帕累托法则 。在任何一个代码库中,有 80% 的代码负责处理“正常路径”(即软件预期要做的事情),而其余的 20% 则用于处理错误、异常和边界情况。

条件判断与编程心理

当我们学习编程时,很自然地会遇到 if-else 语句(这个语句在多数流行的编程语言中都存在)。我们的大脑会立即将 if 与正常路径联系起来,而将 else 与边界情况联系起来。编程中普遍存在一种心理机制:通过在一个大的 if 代码块中包裹主要逻辑,程序员会觉得更加安心。他们会认为这样做能够防止不当输入或异常情况影响代码的主要功能。至于其他情况相对次要,放到 else 里面就好了。

理想很丰满,现实很骨感

这种做法经常会导致以下这样的代码:
if (someConditionIsMet) {// ...// ...// ...// 接下来是 100 行代码// ...// ...// ...// 还有 100 行// ...// ...// ...} else {// 现在,处理边缘情况}
return someResult;
其中一个问题是,边界情况的处理被放在了最后,这使得在上面的代码块添加代码时,很容易忽视 else 内的逻辑。我敢说,大多数人读这段代码时甚至不会注意到 else的存在,直到一个边界情况迫使他们更深入地阅读这段代码。

多层嵌套的陷阱

更糟糕的是,人们倾向于在多个层级上也运用这种模式。因此,写出来的代码更像是这样:
if (someConditionIsMet) {// ...// ...// ...// 接下来是 100 行代码// ...// ...// ...// 还有 100 行if (someOtherConditionIsMet) {// ...// ...// ...// 接下来是 100 行代码// ...// ...// ...if (yetAnotherConditionIsMet) {// ...// ...// ...// 接下来是 100 行代码// ...// ...// ... } else {// 现在,处理边缘情况 }// ...// ...// ... } else {// 现在,处理边缘情况return someOtherResult; }// ...// ...// ...} else {// 现在,处理边缘情况}
return someResult;
代码的多层嵌套是存在很大隐患,也给代码库增加了很多不必要的复杂性。人脑一次只能处理几件不同的事情,因此当面临需要深入分析多个代码层级时,很容易忘记上一层的关键逻辑,导致一些不必要的错误。这也通常是一些 Pull Request 的代码审查发现问题被打回去重新修改的一个主要原因。我们的业务流程已经足够复杂了,多层嵌套又进一步增加了其复杂度。

"箭头代码"的解决方案
我并非第一个提到这种现象的人。实际上,这种深层次嵌套的代码甚至有一个名称。几十年前,Jeff Atwood 就为这种代码风格创造了 [箭头代码](https://blog.codinghorror.com/flattening-arrow-code/) 这个术语。
幸运的是,解决方案相当简单。

抛弃 else,优先处理边缘情况
如果我们抛弃 `if-else` 块中的 `else` 并优先处理这块逻辑,情况会怎么样呢?如果我们不期望某件事经常发生,难到不是先检查它、并在发生时立即返回更好吗?
先处理小的边界情况,如果必要的话提前返回;否则,将主流程保留在函数的最外层。
if (!someConditionIsMet) {// 首先处理那个边缘情况return someResultOrNothing;}
// 主流程可以继续,不需要额外的保护块// ...// ...// ...// 再加 100 行代码// ...// ...// ...// 还有 100 行
return someResult;
同样的思路也可以应用于处理多个边缘情况:
if (!someConditionIsMet) {// 首先处理那个边缘情况return someResultOrNothing;}if (!someOtherConditionIsMet) {// 首先处理那个边缘情况return someResultOrNothing;}if (!yetAnotherConditionIsMet) {// 首先处理那个边缘情况return someResultOrNothing;}// 主流程可以继续,不需要额外的保护块// ...// ...// ...// 再加 100 行代码// ...// ...// ...// 还有 100 行return someResult;
抛弃 else 就可以减少嵌套层数,有效降低代码复杂度。能够让代码更简单,结构更清晰,更容易维护。由于边界情况在函数的顶部得到了处理,开发者在后续添加新代码时不太可能忽略这些情况,从而降低了引入错误的风险。处理边缘情况并早期返回可以减少不必要的计算,从而可能提高代码的执行效率。简化的代码结构更容易被同事理解,从而使代码审查过程更加顺畅,减少了潜在错误和不良实践的传播。
实际工作中你是否见到过多层嵌套导致代码复杂度较高难以维护的情况?你是否认可文中通过边界情况提前处理来减少 else 使用的建议?还有哪些可以有效解决多层嵌套的方法?

END

官方站点:www.linuxprobe.com

Linux命令大全:www.linuxcool.com

刘遄老师QQ:5604215

Linux技术交流群:2636170

(新群,火热加群中……)

想要学习Linux系统的读者可以点击"阅读原文"按钮来了解书籍《Linux就该这么学》,同时也非常适合专业的运维人员阅读,成为辅助您工作的高价值工具书!


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
从一根线条开始,把生活画出来漂亮|欧洲最浪漫的时刻即将开始,这里的圣诞集市全世界最美!“一顿吃102个馒头,8捆线面”:又一网红,被困在新型流量密码里【推荐】圣诞礼盒、秋冬好物…再晚下手就没啦!现在开始囤囤囤!未来3年超适合女性的第二事业,现在开始正好今日直播|《咨询求职攻略 Case准备详解》马上开始,把握最后机会,免费获取面试准备规划建议!第十一章第四节 国家资本主义的社会制度用父母的经历告诉你,如果知道自己 40 岁时被裁员,从现在开始应该做什么麻州黄金地段,自住投资两相宜--本周房源精选--Melrose/Lynnfield/Belmont限时!Tim Hortons惹上官司,现在开始免费发放咖啡和甜甜圈!又降了!SSENSE 低至4折,终于对Essentials卫衣下手了!传任天堂正在开发VR眼镜,谷歌参与其中; VR生存类Roguelike游戏《Bootstrap Island》正在开发中繁华都市里的田园牧歌!第 41 届“”Kelsey农场年度集市”都有什么?女副市长,不是在开房享乐,就是在开房约男人的路上!231103 从现在开始可以吗?一百零七 系主任花钱买轻奢的中产们,现在开始后悔了“这裤子,没运费险我也要退掉!”试穿后…太像丛林野人了吧哈哈哈又降了!SSENSE 低至4折,购物车里的Essentials卫衣终于可以买了!麻州黄金地段,自住投资两相宜--本周房源精选--Lynnfield/Melrose/Belmont开领!现在开始,可免费再领4个新冠居家测试盒从现在开始,学习财务知识吧麻州黄金地段,自住投资两相宜--本周房源精选--Lynnfield/Belmont/Melrose圣诞礼盒、秋冬好物…再晚下手就没啦!现在开始囤囤囤!蔚来,反击从现在开始其實家庭PM2.5及輻射超標或更可怕今日直播|《投行IBD求职如何高效备战》马上开始,把握最后机会,了解投行招聘内幕!一百零八 游石湖星巴克下午的咖啡用父母的经历告诉你,如果40岁时被裁员,从现在开始应该做什么面试攻略 | 面试现场,让面试官把代码写出来?!重要|Alevel一月大考还未开始,2024夏季大考时间表已经出炉!现在开始提前带娃过万圣节!就去这些地方!如何摆脱骨子里的自卑?成功的人都从这3点开始,非常有效兰蔻6折!Essentials罕见半价!AllSaints吐血3折!SW靴子/Myprotein蛋白粉2折起 !
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。