如何接手一坨烂业务代码?如何在烂业务代码中成长?
在我们的职业生涯中,很少有机会可以从零开发一个项目,大部分都是接手别人的代码继续开发,或者做些维护性开发。而且,对于大部分业务系统来说,因为业务导向,需求倒逼,开发工期紧,团队往往都不是很重视代码质量,快速上线是第一要务。所以,很多团队的代码质量一般都不怎么高。埋坑无数、没有文档、也没有注释,代码读不懂、也不敢改,这对于新人来说,会非常苦恼。今天,我们就聊一聊,如何接手一坨烂业务代码,以及如在烂业务代码中的成长?
话不多说,让我们正式开始今天的内容吧!
# 如何接手一坨烂业务代码?
在我过去10年的工作经历中,我接手过很多个代码质量比较烂的项目。这些项目都有很多共性的特点,大部分都已经维护了两三年,甚至五六年之久,代码量很大,有十几万行以上,并且大部分代码都没有任何注释,业务功能非常庞杂,也没有对应的业务文档。
除此之外,代码中还充斥着各种临时解决方案(Workaround)、硬编码(HardCode)、遗留代码(LegacyCode),还有很多匪夷所思的设计。对于有些设计来说,我们称之为“反人类”设计或者“故意挖坑”,一点都不为过。如果没有老员工给你解释上下文,你万万都想不到它为什么这么设计和实现。
实际上,要想接手一个业务系统,前提是要读懂代码,而读懂代码的关键,是要熟悉业务。只要业务搞清楚了,代码只不过是对业务的翻译,对照着业务看代码实现,看懂并不是件难事。不过,我所接手的这几个项目,基本上都是零文档,所有的业务知识都是靠口口相传。所以,搞清楚业务,就成了接手项目最难的事情了。
面对如此庞大的项目代码,没有文档,几乎就是两眼一抹黑。原来参与这个项目开发的老同事,有的离职,有的去做其他新项目,一直问他们也不好意思,所以,大部分情况下,我都只能硬着头皮,通过阅读代码反推业务功能。
如果代码质量比较高,模块划分清晰,命名规范,那通过读代码反推业务,也并非不可能的事情。但真实的情况往往事与愿违,就像我们前面提到的,代码中充斥着临时解决方案、硬编码、遗留代码等各种坑,这就使反推业务变得非常困难。对于代码中的这些坑,尽管我不想一直麻烦同事,但也只有多问才能最快速地解决。
在读代码的过程中,我非常重视知识的文档化,我会把读懂的每个业务都写到文档中。当然,这其中也包括前面提到的各种坑。对于复杂的业务流程,我还会画一些流程图。读代码的过程非常痛苦,花了好几个月,我才有信心说,自己几乎把所有代码都搞清楚了。同时,我也做了一件过去几年都没有人做的事情,那就是补充完整了技术文档和业务文档,之后再有新同事加入,看了我的文档,就可以很快了解代码、了解业务,很快就能上手开发代码。
总结一下,即便代码再烂,只要有完善的业务文档,先理解业务,再去看代码,几乎就没啥难度了。对于零文档的项目,大部分情况下,我们只能通过代码来反推业务。当然,对于有些坑来说,必要的情况下,我们也要询问前辈来搞定。在读代码的过程中,我们要将得到的知识文档化,这也是对公司和团队来说最有价值的部分。
# 如何在烂业务代码中成长?
有人一遇到这种烂业务代码,就觉得很心烦,我反倒不一样。恰恰相反,相比接手好代码,我觉得接手烂代码,虽然过程更加痛苦,但同时也会给我更多施展才华的空间、锻炼技术的机会,我的成长也会更多。
除此之外,很多人觉得做偏底层的开发(基础架构、框架、中间件等开发)才锻炼技术,做业务系统没有挑战,技术上没有成长,对此非常苦恼。实际上,我觉得这种看法是比较片面的。做业务开发的难度不亚于底层开发,做好也不是件容易的事情,同样可以积累技术、锻炼能力。
偏底层的开发更加考验程序员在某一细分领域的技术深度,偏业务的开发更加考验程序员的能力,比如沟通能力、分析问题解决问题能力、权衡取舍能力、架构能力等,毕竟业务多种多样,问题千奇百怪,单一细分领域的经验很难应对所有问题。
实际上,业务系统的开发难度一般来自两个方面:高性能要求和业务复杂。
解决性能问题,你需要具备一定的架构能力,有一定的技术广度,需要对各种基础架构、框架、中间件都有所了解。光了解还不够,还要有一定的技术深度,最好能对原理甚至是源码有所研究。除此之外,还要有一定的使用经验。广度、深度、经验三者配合,这样才能做到恰到好处组合这些技术搭建架构,解决性能问题,并且在出现问题之后才能快速地解决。
应对大型项目的业务复杂性,要想让项目代码一直在你的掌控范围内,你需要有很强的业务建模能力、复杂逻辑的抽象能力、代码翻译能力等。对于一个人的基本素质、基础能力的要求要更高。实际上,对于复杂业务系统来说,对业务的熟悉也能成为你的竞争壁垒,成为升职加薪的砝码。我前面也讲到,低级别的晋升靠技术,比如升阿里的P7,高级别的晋升靠业务,比如升阿里的P8、P9,或者换个说法,高级别的晋升,靠业务比单纯靠技术,更容易一些。
如果你参与的项目,性能要求高、业务也复杂,那恭喜你,好好干就成了。如果你参与的项目,在性能和复杂度上,只兼具其中一点,那也不错,值得一做。如果你参与的项目,既没有性能压力、业务也不复杂,那也别太着急,走着瞧,实在不行再跳槽。
# 课堂讨论
在过往的项目经历中,你有没有像我一样,接手过代码质量比较差的代码?你又是如何顺利接手的呢?
欢迎留言和我分享你的想法。如果有收获,也欢迎你把这篇文章分享给你的朋友。
# 精选评论
点击查看
1.只要你编码意识在提高,接手烂代码应该是常态。 2.这次有幸和业务架构师合作搞中台。(这算不上我理解的中台,只是这么叫而已)
3.首先说一个问题,业务架构师在领域的理解和建模上都很不错,但是在实际开发落地却显得有点刚。我们知道,老单体拆解往往是从圈表开始,这就先动了数据结构。然而既然是烂代码,它的隔离性必然不好(业务层直接调dao层,dao层做数据分发等待)。那么改了数据结构,连带的一切都受牵连,置底向上的重构代码,往往很难发挥新的数据模型的价值,而且这个工作量还很大,把数据迁移算在内,可能2-3个月就这么一层都不见得能重构成功。而对外这一层重构的价值是很不明显的。干2个月,没有看得到的成效,可能就要被砍掉。
4.也感谢团队和架构师的认可,整个中台改造的规划以我的方案为基础。我们做中台是为了增效,主要两个方面。首先,已有业务功能要可以复用(业务流程的可控制,功能的可编排);其次,新功能的加入要尽量少受原有代码的影响(提供扩展性,隔离复杂性或者说分离关注点)。所以我也就这两点自上而下做重构。首先,搭建最外层编排功能的调度层;接着,对已有功能和策略做标准化的适配(适配器:统一多个类的接口设计),这里既有适配和参数转换的工作,也有部分"大方法"拆解重构成小的标准方法的工作。那么一期的重构就在上层编排层的实现和已有功能的适配,加上部分"大方法"的拆解。整个工作差不多在2-3礼拜就能完成。后续的工作就是对每个适配的标准化接口做实现上的重构。(这里数据库的表结构不做变化,但新的功能会基于抽象的领域模型来实现<领域模型到do会兼容老数据结构的转换>。当所有功能基于领域模型实现完后,再对领域模型到do这一层做重构,圈表拆表合并表。)
5.以上,2-3周我们的重构就可以跟着版本迭代发出去。上游编排支持新流程的诉求也能满足。后续工作就落在每个标准功能的重构上,关注点比较收敛。(同一时间,重构过程里也把技术相关的代码抽离业务代码,重定义本项目的dto<老项目没有dto的概率,对外的api包啥都有,有do也有其他组api包的do,非常恶心>)
6.实时上,我认为做重构重来都不只是开发的事。像栏主这样捏着鼻子啃烂代码梳理业务逻辑,我也干过。不同的是,我一直都拉着产品对业务逻辑。重构过程会换业务逻辑实现,甚至会删除整块已经没什么价值的功能。一个项目烂,开发是主要原因,产品也难逃其责。
争哥总结的好,我也是一名经历过烂代码的受害者到受益者的过程,对遗留业务逻辑的梳理总结沉淀尤其重要,同时也是让老板认识你在烂代码中有产出的关键出口。 关于基础架构开发和业务开发的总结,很有启发,我现在是游走于两者之间平台开发,对沟通能力的不足深有感触
和老师感同身受,我也是接手了一个几乎没有文档和注释的项目,没办法只能补,现在我们一旦有新的需求我都要求先做好需求分析并文档化,一来是为了项目验收二来也是为了新来的同事有文档可查,避免两眼抹黑的情况……
年初加入一家公司,项目差不多有56年了,几乎没有任何的文档,熟悉该项目的产品经理,程序员几乎都离职了,唯一熟悉的老大每天又很忙,不能经常问他,实在是太痛苦了,不敢动,不敢改,数据库字段也没有注释,代码写的很随意,果断跳槽了,我之前写代码也特别不注意规范和命名,自从来了新公司,虽然公司不大,后端开发差不多就三个人,但是代码结构看起来非常的舒服,命名规范,老大还是对我写的代码进行CR,老大是一个非常注重细节和规范的人,对自我的提升还是挺大的,有时候工期紧张,保证代码规范还是有一定的难度的,都是先上线再说~
我现在正面临这样的一个问题,目前项目已经在重构中,我也正打算把文档一一的补回来,但是实在太多。
现在苦恼怎么补,补哪些内容,补到什么程度。
不知道老师能否给我一点建议,最好能带点实例,谢谢。
哈哈,不一定是接手别人的烂代码,有可能是自己之前写的烂代码,所以在增加或者是修改功能时,如果是不大的代码块还是需要重构的。前提是写好单元测试。
感觉经常碰到自己写的烂代码呢
本节课满满的正能量
这篇真不错!争哥牛逼!🤣
即将接手一个烂项目,锻炼自己的机会来了😂
深有感触,接触的代码以前没有文档,阅读起来真的很难。现在写完一段代码,都会写一个文档来解释,然后可以帮助新人更好理解,前人栽树,后人乘凉