大家好,欢迎来到停止重构的频道。
本期我们讨论一个比较开放的问题,如何写出规整易读的代码。
这听起来是一个小问题,但是实际上,所谓的屎山代码说白了就是杂乱无章的代码,理解的时间要比修改的时间多很多。
这些不可估量的理解成本,慢慢积累起来就是无限延期和无穷加班。
我们详细讨论下面几个问题:
1、没有注释的代码一定是屎山吗?
2、提升代码可读性的秘诀?
3、我们认为的代码更优形态
没有注释的代码一定是屎山吗?
首先讨论一个问题,没有注释的代码一定是屎山代码吗?
我在上学的时候是认为,注释肯定是能提升易读性的,不写注释的话总感觉过两天就看不懂了。
而且写注释的过程也能进一步检查程序的逻辑,提前发现一些BUG。
但是参加工作后,却慢慢少写注释了。
这当然有项目进度、工作压力等因素,项目主管总是催着快点完成任务。那谁又愿意在加班后还继续加班写注释呢?
当然,这只是表面的因素。
更重要的是,在多人参与、长时间迭代升级的软件项目下,注释对代码理解的帮助其实没那么大。
图中示例看起来还算好理解是因为代码行数少,如果这是一个两三百行且包含四五层嵌套if/else的话,那理解起来肯定是晕头转向的。
而且实际工作并不是看懂一个代码片段就可以了。
你往往需要理解十几个函数,才能判断BUG位置。修改了BUG也可能对其他功能造成影响,BUG越改越多。
何况你看到的注释还可能是个陷阱。
注释可能是错误的,可能来自于当时开发人员对某个API的错误理解。
注释也可能是很旧的,是最开始的开发人员写的,但是之后修改的人都没有更新。
当然,这些都可以简单地说一句,个别开发人员太不负责任了,或者团队规范没做好活该。
但是主导了这么多项目后,我深有体会。
注释的维护本身就是一件非常奢侈的事情,很难要求每个开发人员都自愿花时间去写注释。
而且什么是必要的、清晰的、完整的注释也很难给出标准,难以给出标准的事情就,没有执行性可言。
所以我们认为,屎山代码跟注释没多大关系。代码结构混乱、难以理解的代码才是屎山。
提升代码可读性的秘诀
那如何提升代码可读性呢?
首先是工程结构要非常清晰,平衡好软件结构、开发效率、维护扩展成本的关系。
关于工程结构规整化的问题,已经在往期前端规整化、后端规整化里提到过了,这里不作展开。
这里着重讨论单个函数、代码片段如何写,才能提升可读性。
首先需要在变量名、函数名、类名等定义时写明它们的作用,而不是用一些随便的、奇怪的拼音缩写。
代码即注释,这样就能很大程度提升代码的可读性。
另外,我们认为易读的代码片段应该是单层流程化的。
也就是避免多层嵌套的if/else,可以通过提前返回、抽离函数等方式实现。
单层流程化的代码可以快速理解逻辑,每一个步骤只有通过和不通过。如果在每个流程前添加一下简单注释,就更清晰了。
当然,完全的单层流程化代码可能会造成过多的碎片函数,所以单层的限定不需要太过苛刻,只需要尽量降低代码嵌套层数就可以了。
我们认为的代码更优形态
以上的方法只能提升代码的易读性,顶多从3天的理解时间下降到1天。
但开发人员不一定能完全遵守,而且根据破窗效应,只要有一个开发人员不遵守,慢慢地整个项目代码都会变得乱糟的。
那是否有什么方法?
可以让代码保持易读规整,开发、维护、扩展的效率大幅提高的同时,人员流动也不会造成影响呢?
这是我做架构师这几年一直在探索的问题。
比起各种花里胡哨的工具、框架,我更看重开发过程、项目质量。这些年也摸索试验出了一套顶层架构的设计方法论。
首先代码应该分离为模块代码、业务代码两层。模块代码是通用的功能代码,业务代码是对模块进行使用顺序编排以实现具体业务功能。
模块代码实现的是通用功能,需要写代码实现功能。
以后端举例模块可以是检查必要参数、权限校验、大文件分片上传等模块。
前端的话模块可以是通用的播放器、聊天框、后端请求模块等。
模块要求完全独立,且可以单独运行调试。
另外,模块要求采用统一的使用方式,方便业务代码进行流程编排。
由于模块的这些特性,允许模块无条件复用在别的项目。
也可以不断积累扩展模块池规模,项目成本将越来越低。
另外,即使某个模块是临时快速开发的,也可以不需要太多顾虑地进行单独修改重构后替换。
业务代码主要是对模块使用顺序进行编排,以实现具体功能。
由于模块约束了统一的使用方式,所以业务代码可以不需要写代码。
开发人员可以用Json配置文件等方式代替写代码,最后在程序运行前通过代码生成器生成真正的业务代码即可。
最终生成的业务代码其实就是极度规整化的单层流程化代码。
以后端举例,业务编排是对一个API处理流程的编排,如第一步检查必要参数、第二步检查权限、第三步插入数据。
前端的话,业务编排是对一个事件响应流程的编排,如提交表单按钮点击后,第一步调用表格模块获取资料,第二步调用后端通信模块请求后端,第三步调用提示模块显示结果,第四步调用导航模块跳转页面。
按以上方式分离代码后,可以让团队分工合作更加紧密顺畅。
业务代码由于不需要写代码调试,可以交由一些经验不足的开发人员完成。
模块代码开发,虽然要求有一定开发经验才能胜任,但是可以复用。
这样分工可以从根本上缓解开发工作量化的问题,效果就是成本预算更精准,更低计划预测也将更准确。
我们之前发布的前端框架Trick、后端框架Once、云计算框架Hive。
只有Once实现了以上所有的设想。而Trick、Hive由于数据流转、多线程同步等问题,当时是还没有实现业务代码的无代码编排化的。
但即使是这样,一个后端人员也足够支撑4-5个前端人员了。
而2023年我们解决了这些问题,Trick2、Once2、Hive2实现了以上的所有设想。
它们将在今年内整理完发布,这也会成为后续低代码的内核,敢兴趣的小伙伴可以关注一下。
总结
当然,以上只是我们的看法、想法、做法。
如果有什么建议、意见,或者你探索出了更好的方式,欢迎在评论区一起讨论。