设计模式学习笔记 - 开源实战二(中):从Unix开源开发学习应对大型复杂项目开发

概述

项目越复杂、代码量越多、参与开发人员越多、开发维护时间越长,我们就要越重视代码质量。代码质量下降会导致项目研发困难重重,比如:开发效率低,找了很多人,天天加班也出活不多;线上 bug 频发,查找 bug 困难。

导致代码质量不高的原因有很多,比如:代码无注释,无文档,命名差,层次结构不清晰,调用关系混乱,到处 hard code,充斥着各种临时解决方案等等。

如何才能保证代码质量呢?

当然,首要的是团队技术素质过硬,能够适当地利用设计原则、思想、模式编写高质量代码。此外,还有一些外在的方法可循。

本章,就从研发管理和开发技巧的角度,来讲解下面对大型复杂项目的开发,如何长期保证代码质量,让代码长期可维护。


1.吹毛求疵般地执行编码规范

严格执行代码规范,可以使一个项目乃至整个公司的代码具有完全统一的风格 ,就像同一个人编写的。而且,命名良好的变量、函数、类和注释,也可以提高代码的可读性。编码规范不难掌握,关键是要严格执行在 Code Review 时,我们一定要严格要求,看到不符合规范的代码,一定要指出并要求修改。

但是,实际情况往往事与愿违。虽然大家都知道优秀的代码规范是怎么样的,但在具体写代码的过程中,执行得却不好。我觉得,这种情况产生的主要原因还是不够重视。很多人觉得,一个变量或函数命名成啥样,关系并不大。所以命名时不推敲,注释也不写,Code Review 时也是一幅事不关己的心态,觉得没有必要太抠细节。日积月累,项目代码就会变得越来越差。所以我这里还是要强调一下,细节决定成败,代码规范的严格执行极为关键。

2.编写高质量的单元测试

单元测试是最容易执行且对提高代码质量见效最快的方法之一 。高质量的测试不仅仅要求测试覆盖率高,还要求测试的全面性,除了测试正常逻辑外,还要重点、全面地测试异常下的执行情况。毕竟代码出问题的地方大部分都发生在异常、边界条件下。

对于大型复杂醒目,集成测试、黑盒测试都很难测试全面,因为组合爆炸,穷举所有测试用例的成本很高,几乎是不可能的。单元测试就是很好的补充。它可以在类、函数这些细粒度的代码层面,保证代码运行无误。底层细粒度的代码 bug 少了,组合起来构建而成的整个系统的 bug 也就相应的减少了。

3.不流于形式的 Code Review

如果说,很多工程师对单元测试不怎么重视,那对 Code Review 就是不怎么接受。很多人都觉得 Code Review 不可能很好的执行,形式大于效果,纯粹是浪费时间。

是的,即便 Code Review 做的再流畅,也是要花时间的。所以,在业务开发任务繁重时,Code Review 往往会流于形式、虎头蛇尾,效果确实不怎么好。

但是,我们并不能因此就否定 Code Review 本身的价值。在 Google、Facebook 等外企中,Code Review 应用得非常成功,已经成为开发流程中不可或缺的一部分。所以,要想真正发挥 Code Review 的作用,关键还是要执行到位,不能流于形式

开发未动、文档先行

对于大部分工程师来说,编写技术文档是件让人 "反感" 的事情。一般来讲,在开发某个系统或者重要模块、功能之前,我们应该先写技术文档,然后,再发送给同事审查,在审查没有问题的情况下再开发。这样能够保证事先达成共识,开发出来的东西不至于走样。而且,当开发完成后,进行 Code Review 时,代码审查者通过阅读开发文档,也可以快速理解代码。

此外,对于团队和公司来讲,文档是重要的财富 。对新人熟悉代码或任务的交接等,技术文档很有帮助。而且,作为一个规范化的技术团队,技术文档是一种摒弃作坊式开发和个人英雄主义的有效方法,是保证团队有效协作的途径

持续重构、重构、重构

我个人反对平时不注重代码质量,堆砌烂代码,实在维护不了就大刀阔斧的重构甚至重写。有时候,因为项目代码太多,重构很难做彻底,最后又搞出来一个四不像的怪物,这样就更麻烦。

优秀的代码或架构不是一开始就设计好的,就像优秀的公司或产品也都是迭代出来的 。我们无法 100% 预见未来的需求,也没有足够的精力、时间、资源为遥远的未来买单。所以,随着系统的演进,重构是不可避免的

虽然我刚刚说不支持大刀阔斧、推倒重来式的大重构,但持续的小重构我还是比较提倡的。它也是时刻保证代码质量、防止代码腐化的有效手段。换句话说,不要等到问题堆得太多了再去解决,要时刻有人对代码的整体质量负责,平时没事就改改代码。千万不要觉得重构代码就是浪费时间,不务正业。

特别是一些业务开发团队,有时候为了快速完成一个业务需求,只追求速度,到处 hard code,在完全不考虑非功能性需求、代码质量的情况下,堆砌烂代码。实际上,这种情况还是比较常见的。不过没关系,等你有时间了,一定要记着重构,不然烂代码越堆越多,总有一天代码会变得无法维护。

6.对项目与团队进行拆分

我们知道,团队人比较少,比如十几个人时,代码量不多,不超过 10 万行,怎么开发、怎么管理都没问题,大家都比较了解彼此做的东西。即使代码质量太差了,我们大不了把它重写一遍。但是,对于一个大型项目来说,参与开发的人员会比较多,代码量很大,有几十万、甚至几百万行代码,有几十、甚至几百号人同时开发维护,那研发管理就变得极其重要。

面对大型复杂性项目,我们不仅仅需要对代码进行拆分,还需要对研发团队进行拆分上篇文章我们讲到了一些代码拆分的方法,比如模块化、分层等。同理,我们也可以把大团队拆分成几个小团队。每个小团队对应负责一个小的项目(模块、微服务等),这样每个团队负责的项目包含的代码都不至于很多,也不至于出现代码质量太差无法维护的情况

总结

实际上,上面刚刚讲的 6 条方法论都没啥新奇的,网上也有很多的信息,最后谁做得好,关键在于执行和细节。

有人说,我们做了单元测试、Code Review 了,但到最后,项目还是一堆 bug,代码质量还是很差。这个时候,我们就要去思考一下,单元测试、Code Review 做的到底够不够好,从决策到执行再到考核是否形成了闭环。不能口号喊的 100 分,落实到执行只有 50 分,最后又没有很好的考核机制,好坏大家也都不知道。所以,切忌敏与言而讷与行。

此外,刚刚所讲的方法都治标不治本。软件开发过程中的问题往往千奇百怪。要想每个问题都能顺利解决,除了理论知识和经验之外,更重要的是具备分析问题、解决问题的能力。这也是为什么很多公司重视应届生招聘,希望从一开始招聘一些有潜力的员工。找到对的人、用对好的人,打造优秀的技术文化,才是一直保持卓越的根本。