最近 CR 了这样一段代码:
我们团队的变量命名规范是小写驼峰,但是这里可以看到,一个 http api 接口请求的工具函数的入参却是下划线。这是一个内部项目,前后端都是我们团队开发的。这个项目的代码随处都能看到这样的不符合规范的痕迹,而且屡禁不止。我不禁在想,为什么会这样?
先探究一下这个问题的表面原因,让我们从底层开始:
- DB 表结构按照团队规范,字段名是下划线分隔的
- node 服务定义 entity 的时候,直接复用 DB 表结构字段名
- service 模块在查询 DB 之后,直接回吐结果,所以 service 类返回的数据结构的变量名也是下划线的
- node api 的 controller 通过调用 service 模块的函数,获取数据处理之后,也直接回吐下划线的变量名的数据结构
- 因为 node api 的接口协议是下划线的,所以 web 页面请求 http api 的出入参也是下划线的,如上图所示
- 因为 http api 返回的结果是下划线的,然后页面逻辑直接使用,最后,页面逻辑也出现了大量下划线
这是一段挺长的链路,只要我们在后面的任意一个环节处理一下变量名的转换,都能避免这个问题,但是并没有。
为什么会这样?稍微探究一下这里的深层原因,也是挺有意思的。
首先,项目启动时没有严格把控代码质量。这里的原因有很多,比如项目工期紧、主要以完成功能为主、内部项目不需要要求这么严格、项目启动时是直接 copy 另外一个项目的,那个项目也是这样写的等等。但是,这些统统都是借口!我是要负主要责任的。
其次,没有开发同学想过要去优化这里的代码。参与这个项目的同学并不是不知道如何去解决这个问题,但就是没人想要去解决这个问题。大家更多的是选择“入乡随俗”,别人这么写,我也这么写吧。
最后,Code Review 没有严抓。问题都是越早处理成本越小,如果在早期我们就开始严抓 Code Review 的话,说不定就能及时改善这个问题了。
这个案例是一个非常真实的破窗效应案例,这里面有不少地方值得我们深思的。
首先,它会污染整个项目。如果我们在项目的一开始就没有把控好代码质量,那我们的项目代码很快就会被污染。最开始的开发同学可能知道历史原因,自然不会觉得不自然。后续加入的维护者看到项目代码是这样子的,就会误以为这个项目的代码规范就是这样子的,于是也“入乡随俗”,最终整个项目的代码就被污染,破烂不堪。
其次,它会污染依赖的项目。比如这里就是 node 项目先被污染,对外提供的 api 也受到污染,然后调用这些 api 的 web 项目也被污染了。很多时候,api 的接口协议都是由后端开发来定,如果碰到一些缺乏经验的后端开发,前端同学会收到一些很奇怪的接口协议,比如字段命名规范不统一,冗余字段,设计不合理等等,由于前端的话语权较弱的缘故,很可能会被动接受,如果处理不当,前端项目的代码就会受到污染了。
最后,它会污染整个开发团队!初创的开发同学就不说了;后续的维护者看到代码是这样子的,不是错误认知这个项目的代码规范,就是错误认知团队的代码规范;更为糟糕的是,阅读项目源码的其他同学也会受到污染:“哦,原来别人也是这样写代码的”。噩梦由此而生...
破窗就像病毒一样,快速并疯狂地污染整个项目代码,然后传染给开发团队,最后扩散到其他团队。这个病毒传染的范围很广,速度很快,一不留神,整个团队就会沦陷。那我们应该怎样医治呢? 主要有 3 个方向:
首先,增强个人免疫力。形成个人的编码风格,然后坚持它,这是治本的良方。良好的编码风格是不会损坏个人的编码效率的,反而会有助于提升个人的研发效率,主要体现在以下几个方面:
- 减少低级错误
- 提升代码的可阅读性,提升代码的可维护性,从而提升团队协作效率
- 形成“肌肉记忆”,提升编码效率
- 避免返工,主要体现在糟糕的设计问题和编码风格冲突问题
其次,做好防护,避免传播。比如我们这个简单的案例,在整个链路的任何一个环节,都能轻松处理这个问题,这样就不会传播到后面的环节了。很多人碰到一些历史破窗代码时,可能会觉得修复这些破窗成本太大了,那就不要去修复,只需要保证自己写的新代码是良好的,也是一个不错的方案。已经中毒的人我们没有能力医治的时候,起码,我们可以认真做好防护,避免病毒进一步传播!
最后,对症下药医治。只有千日做贼,那有千日防贼,我们总是需要想办法医治这个病,而治病的药方就是重构。这里就不深入讲了,重构也是个大学问,只需要知道,越早重构,成本越低,比如在 Code Review 的时候就要严抓这些问题,并跟踪修复情况。
不知道,你的“免疫力”修炼得怎么样了?
【讨论问题】
除了这里的案例,还有很多其他类型的破窗,你都碰到了哪些?
欢迎在评论区分享你的想法,一起讨论。
本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。