写点什么

为什么你写的代码别人看不懂?

  • 2020-03-19
  • 本文字数:3244 字

    阅读完需:约 11 分钟

为什么你写的代码别人看不懂?

好的事物都是在结构和混乱的健康平衡中产生的。

为什么你的代码这么潦草?

为什么每个开发人员都认为自己编写的代码是完全可以理解的?为什么同一个开发人员不能看懂和理解别人编写的代码,从而很少能对其进行维护呢?


是因为他们写的代码都很潦草。也就是说,代码现在可以正常运行,但由于它相当混乱,不具备很好的可扩展性或通用性。计算机科学家是个例外 — 他们编写的代码很“漂亮”,但不起作用。

原因 1:对于计算机科学家来说,编码是一门艺术。对其他人来说,它仅是个工具

计算机科学家编码是因为他们想编码。其他人编码是因为他们想完成工作。


一个普通的开发人员会根据他们能想到的第一个想法来构建程序。然后他们会在这个想法的基础上继续延伸,直到构建出类似 MVP 的东西。通常情况下,他们甚至不会考虑是否还有其他可行的方法。


相反,计算机科学家会考虑实现的各种方案,权衡每种方案的利弊。几周之后,他们可能还只是编写了一段漂亮但仍然不能完全运行的代码,因为计算机科学家还没有决定好输出要采用什么格式。


很多潦草代码的产生是由于开发人员仅从一个简单的工具开始,然后就有机地增长代码造成的。相比之下,计算机科学家通常会先构建一个结构框架,然后再在框架内实现编码。



有些代码看起来很整洁,但实际上却很混乱。图片来自UnsplashNikita Vantorin上传


为了避免 Coder Block 能按时交付,采用有机的方法是最好的。但是,如果我们想要编写可持续的代码,可能就需要将结构框架放在第一位了。

原因 2:开发人员并不总是以读者为中心来编码

即使是在协作项目中,开发人员也倾向于在编码时仅考虑其功能。他们这样做时,就会忘记“代码也是需要维护”的这一事实。


问题在于这种心态会适得其反。当开发人员想在三个月后再添加一个特性时,他们可能连自己都无法理解自己编写的代码了。这种情况比你想象中的要更常见!


当另一个开发人员被要求实现这个新特性时,情况会变得更加复杂。由于项目规模大小的不同,理解其他人编写的代码可能需要花费几天到几周的时间。

原因 3:风格很重要

每个人都以不同的方式编码。有人讨厌行注释,有人则喜欢。有人会在第一行的上面注释它们的功能,有人则会在第一行的下面注释。有人喜欢使用 switch 开关语句,有人则讨厌。


这就是为什么一段代码对一个人来说可能很可怕,但对另一个人来说却很好。


当你独自工作时,这没什么问题。但如今,很多软件都是协同构建的。因此,在项目的早期,制定风格指南是很重要的。


当然,我们还需要确保所有的开发人员都遵守它。否则,我们将以代码更加混乱而告终,因为此时代码会是各种不同约定混杂后的产物。



及时修复是有益的,但从长远来看可能会导致大混乱。图片来自UnsplashMuhannad Ajjan 提供

理由原因 4:即时奖励的谬论

你被一个问题困扰了很几天,当你终于找到了解决方案时,你是否会感到兴奋?这是一个非常激动人心的时刻。


问题在于,当开发人员追求快速修复时,往往会忽略长期的问题。例如,他们可能修复了一个 bug 或者添加了一个特性,但是他们没有意识到代码结构已经过时了。


这意味着每当他们要添加一个新特性时,都不得不投入更多的工作。相反,从长远来看,对程序进行一次重构,当添加更多新特性时,将会变得更加容易。


如果你更喜欢快速修复而不是解决潜在的问题,没关系,这样的人很多。人类的奖励系统更容易受到短期修正而不是长期变化的影响。但这样一来,我们就欠下了“技术债”。从长远来看,这会让我们付出更多代价。

整洁 vs 混乱的危险

声称自己总是编写整洁代码的开发人员要么是撒谎,要么是高估了自己。也就是说,我们不想编写太整洁的代码是有原因的:


  • 如果你的目标是从头开始编写整洁的代码,那么你就增加了 Coder Block 的风险。为了避免主要的 Block 发生,最好是在一开始时就有机地增加代码。这尤其适用于初学者。

  • 一些开发人员会花一整天的时间来清理他们的代码,只是为了美观,而没有其他原因。当然,如果还有很多其他协作者,或者代码可以以任何一种方式来呈现,这都是无可厚非的。但通常情况下,润色代码的效果就像一般的医疗整形手术一样——可能看起来很不错,但并不解决任何更深层次的问题。


另一方面,我们也不希望代码太混乱。太混乱会使我们的代码无法维护。缺乏维护会导致代码“腐烂”,从长远来看,项目将会被丢弃,因为它们的弊大于利。


因此,我们需要的是在快速拿结果和代码可维护性之间维持健康的平衡。大多数开发人员都会陷入代码混乱的困境,所以提高整洁度才是解决之道。好消息是,一些好的习惯可以对开发人员的代码整洁度和生产力产生巨大的影响。


技巧 1:尽早进行测试并提高测试频度

一些开发人员对他们的技术非常有信心,以至于他们在不运行任何测试的情况下就构建完了整个项目。但是,除非手头的任务是完全无关紧要,否则只会适得其反。


当他们尝试编译或执行程序时,屏幕上就会充满各种错误消息。或者,更糟糕的是,直到几个月后,当用户意识到程序没有按照预期运行时,错误才会被发现。


这些都是不好的做法。如果在技术部门工作可以教会我们什么的话,那应该是:


如果你没有对所有场景进行测试,就永远不要假设某些东西能像预期的那样运行。


尽可能快速地构建一些可执行的代码。即使它非常非常的简单。一有机会就测试一下它。这样你就可以在错误构建完之后能立即修复它们了。

技巧 2:结构良好但格式混乱

只要代码的底层结构是好的,追求快速修复也是可以的。但实际情况是,开发人员试图在混乱或过时的代码结构中实现快速修复。


在这种情况下,最好花时间重构代码。如果需要修复的代码没有正确的注释,或者变量命名词不达意,那也不是没得救。但是,试图在充满 bug 的代码中构建一个干净的特性却是浪费时间和资源的,不管怎么样,我们可能需要重写很多其他特性。


因此,在代码整洁度和速度之间进行选择的一个很好的折衷方案是保持底层结构的整洁和更新,但在细节上可以容忍混乱。



把“恶魔”留在细节,图片来自UnsplashAlvaro Reyes上传

技巧 3:为重构分配时间

每次你搞得一团糟,你都是在制造技术债。就像货币债一样,你借贷的时间越长,它的成本就越高。


另一方面,花上几天甚至几周的时间来清理代码,对一般的开发人员来说,并不能受到鼓舞。这就是为什么建立一个每天都能还一点债务的习惯是非常有用的。


一个好的开始方法是每天花费 15%的时间来进行重构。我称之为时间规则。你会为你能改进的代码量感到惊讶的!

技巧 4:留下比你发现时更整洁的代码

我把这叫做“厕所规则”。如果每个人在离开公厕时,公厕至少要和他们进入时一样干净,那么他们将会处于无可挑剔的状态。


从大多数公共厕所的状况来看,现实并非如此。维持这样的规则需要每个开发人员都遵守纪律,而这反过来还需要一个优秀的管理者。


但遵守这种纪律是值得的,因为随着时间的推移,回报是巨大的。我们不可能通过做不可能的事情来实现不可能。我们只需通过做一些好的决定就能实现它,并且每天都朝着这个目标迈出一小步即可。

技巧 5:请求审查!

有时,代码会很混乱,是因为开发人员不知道如何才能做得更好。例如,代码可能在使用 map 更简单的情况下使用了 switch 语句。在这种情况下,来自高级开发人员的建议就是关键。


建立代码审查的例程可以帮助我们创建一个反馈机制。这将会改善年轻开发人员的学习曲线,并能培养一种健康讨论的文化。


就像“厕所规则”和时间规则一样,例程是关键。请求审查应该是初级开发人员的一种习惯,提供建议应该是高级开发人员工作的一部分。


理想情况下,审查时间应该是开发团队核心流程的一部分,而对关键审查建议的总结也应是每次会议的一部分。


平衡结构与混沌

编写太过整洁的代码会浪费时间和资源。编写潦草的代码比遭遇 Coder Block 而根本无法交付要好得多。


另一方面,潦草的代码不灵活且难以维护。这五条规则将有助于使我们的代码变得更整洁,且无需浪费时间。正如生活的各方面一样,好的事物都是在结构和混乱的健康平衡中产生的。


延伸阅读:


https://towardsdatascience.com/four-reasons-why-everyone-except-for-computer-scientists-writes-sloppy-code-b8505254e251


2020-03-19 08:283055
用户头像
刘燕 InfoQ高级技术编辑

发布了 1112 篇内容, 共 539.7 次阅读, 收获喜欢 1977 次。

关注

评论

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

spark调优(六):大家好才是真的好——广播变量

怀瑾握瑜的嘉与嘉

spark 7月月更

Linux下QT配合OpenCV完成图像处理(实现基本的人脸检测)

DS小龙哥

7月月更

LeetCode-111. 二叉树的最小深度(java)

bug菌

Leet Code 7月月更

Android/Unity大乱斗-完整双方集成交互指南

芝麻粒儿

android Unity 7月月更

查找——二叉排序树(一)

乔乔

7月月更

MFC|自绘CStatic刷新不及时问题

中国好公民st

c++ 7月月更

iOS中的Block(初步认识)

NewBoy

ios 前端 移动端 iOS 知识体系 7月月更

QT | VS2017 + Qt5.14.2环境搭建

YOLO.

环境搭建 vs Qt Creator 7月月更

浅谈 Slack Channel 支持的一些提高工作效率的特性

汪子熙

远程办公 即时通讯 SAP Slack 7月月更

镍氢电池的特性和使用方法(FDK镍氢电池充电机制)

不脱发的程序猿

嵌入式 汽车电子 镍氢电池 镍氢电池充电逻辑 FDK镍氢电池

谈谈JavaScript的作用域及作用域链

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

7月月更

【C语言】进阶指针night

謓泽

7月月更

【LeetCode】最长的斐波那契子序列的长度Java题解

Albert

LeetCode 7月月更

语音聊天源码——语音聊天源码开发设计搭建

开源直播系统源码

软件开发 直播系统源码 开源源码 语音聊天源码 语音社交软件

从0开始的 TypeScriptの十四:内置工具类型

空城机

typescript 7月月更

list的使用方式

小肉球

qt 7月月更

【答疑解惑】 裁员浪潮中,N+1 到底指什么?

面试官问

互联网裁员 N+1

对接企业微信,客户关系管理也可以很简单!

CRMEB

微信内H5页面唤起小程序&App

南城FE

前端 微信开发 7月月更

ArkUI常见问题汇总【系列3】

坚果

HarmonyOS Open Harmony 7月月更

深入Ceph原理包含核心算法Crush说明和通信机制原理(五)

Lansonli

云原生 Ceph 7月月更

激情的开头,大意的结局,Python反爬加更,好友求助米哈游的API,给他安排上

梦想橡皮擦

Python 爬虫 7月月更

python 中Mixin混入类的用法

杨彦星

Python

【古月21讲】ROS入门系列(2)——发布者Publisher、订阅者Subscriber的编程实现+自定义话题消息编程实现

秃头小苏

ROS 7月月更

如何控制css鼠标样式以及扩大鼠标点击区域

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

7月月更

服务网格中 sidecar 流量治理与多协议嗅探

博文视点Broadview

Room:又要写业务代码了?看看我吧,给你飞一般的感觉!

编程的平行世界

数据库 Android; android jetpack

【Debug】VS EXE运行“应用程序无法正常启动(0xc000007b)”

柒号华仔

debug 7月月更

java零基础入门-综合案例(File类+递归)

喵手

7月月更

有证书有目录!|海泰密码服务平台

电子信息发烧客

mysql进阶(三)游标简易知识点汇总

No Silver Bullet

MySQL 数据库 游标 7月月更

为什么你写的代码别人看不懂?_AI&大模型_Rhea Moutafis Following_InfoQ精选文章