身为一名程序员,我们经常会调侃自己每天的工作就是在屎山上拉屎。这里的屎山还有一个更好的名称,叫做技术债务。
技术债务是怎么产生的
我参加过许多不同的项目,而基本上每个项目都会存在或多或少的历史债务。实际上,愿意给到资源去解决历史债务的团队,更是少之又少。
业务功能的快速迭代,往往意味着缺少长期的规划和设计,架构演化和迭代更是无从谈起。我们总会吐槽自己在屎山上拉屎,但许多项目的实际情况是生命周期很短,业务或许还未稳定就已经被淘汰。
这样的情况下,技术债务的产生是必然的,我们写的每一行代码都可能成为历史债务。因为我们的业务在不停地快速试错和迭代,项目也在不断地变更和发展。技术方案没有唯一解,最合适的技术方案想必也会跟随着项目产生变化。
即使我们很幸运地遇到了生命周期较长的项目,也不可避免地在业务快速发展的时候忙于堆叠功能。直到现有架构的维护成本过高,影响到后续功能迭代时,才会想起来需要进行技术变更。
当架构设计需要进行变更、新技术引入时,过往的方案设计很容易就成为了历史债务,这是一个必然过程。
虽然技术债务躲不了,那当技术发生变更的时候,我们可以通过一些方法使其产生更少的债务。
技术方案预研
这些年的前端技术变更十分迅猛,很多人会在项目中引入新技术,来获得更高的开发效率或是更好的性能。除此之外,我还见过许多技术的引入,单纯是为了跟上新的技术栈,或是拿业务代码来做试验。
最糟糕的还是为了汇报引入的技术,我在工作中已经见过无数为了晋级答辩强行造的轮子或是引入新技术。在答辩通过之后,他们往往会继续去攻陷下一个“技术亮点”,留下来大堆大堆的技术债务。当然,这也不能怪留下债务的人,很多时候他们也只是想办法在规则范围内获得更多的利益。
那么,当我们遇到需要引入新的架构设计或是技术的时候,可以进行较深入的技术方案预研,来尽量避免引入更多的技术债务。确保了技术方案的最优化,可以避免开发过程遇到问题需要推翻重做,也可以提前评估预期的效果和引入的技术债务如何解决等问题。
技术预研的话,可以从几个方面考虑起:
- 项目现状/痛点分析。
- 业界方案调研/方案选型。
- 架构可拓展性。
1. 项目现状/痛点分析
在进行技术方案调研的时候,我们需要首先结合自身项目的背景、存在的痛点、现状问题进行分析,只有找到项目的问题在哪里,才可以更准确、彻底地去解决这些问题。
很多人在拿到一个不熟悉的项目时,第一反应经常是重构它。说实话,要把重构这项工作做好,往往是吃力不讨好。对此,个人的建议是可以先开发和维护一段时间,确切知道项目的实际情况后,结合业务未来的规划,再来考虑是否需要进行重构工作,亦或是局部优化。如果说业务已经稳定,且不会再用什么新的功能了,除非是 bug 多到无法解决,否则就不需要投入过多的精力在这里。
项目痛点是什么?直白来说,就是我们每天在吐槽的事情,还有我们认为没有意思的事情,比如:糟糕的历史代码、枯燥又重复的开发工作、历史债务导致的开发效率低下等问题。相比于每天都在吐槽,我们可以动动手花点时间把问题解决,这样每天就可以有更多摸鱼的时间了(不是。
更多情况下,是项目现有的设计,无法支撑后续功能的快速迭代了。
我们可以主动寻找项目存在的问题和痛点,并尝试去解决。不同的项目或是同一个项目的不同时期,关注的技术点都会不一样。对于一个前端项目来说,技术价值常常体现在系统性能、稳定性、可维护性、效率提升等地方,比如:
项目情况 | 项目特点 | 关注点 |
---|---|---|
用户量较大的项目 | 对系统稳定性要求较高 | 需要关注是否会导致历史功能不兼容、是否会引入新的问题等 |
大型复杂的项目 | 涉及多人协作,对系统可维护性要求高 | 需要避免每次的改动都会导致性能和稳定性的下降,如何提升协作开发的效率等 |
一次性的活动页面、管理端页面开发 | 如何提高开发效率 | 可以使用配置化、脚手架、自动化等手段来提升页面的开发和上线效率 |
2. 业界方案调研/方案选型
项目的痛点可以转化为一个目标方向,比如:
项目痛点 | 优化方向 | 优化措施 |
---|---|---|
加载慢 | 首屏加载耗时优化 | 减少首屏代码/异步加载/懒加载等 |
开发效率低 | 提升项目自动化程度 | 配置化/脚本工具/CI、CD 等 |
多人协作容易出问题 | 提升系统稳定性 | 自动测试回归等 |
有了目标之后,我们就可以进行业界方案调研和选型。
比如说,项目代码已经很庞大了,模块之间调用关系过于凌乱、模块状态的数量过多导致修改和监听复杂等等。那么,这种情况下,我们则需要引入新的技术或是架构设计到项目中,比如使用依赖注入来管理模块间的依赖关系,使用状态管理工具来维护应用各模块以及全局的的状态。
具体到前端页面开发来说,前端状态管理工具也有很多,常见的比如各框架自带的 vuex、redux,以及比较热门的 mobx 等,具体的引入可以结合项目自身的情况比如使用的框架、项目技术栈等来进行选型。
除此之外,有时候我们会遇到一些现有开源工具无法直接在项目中的问题,这种时候我们往往需要“造轮子”,即参考业界成熟的技术方案,结合项目实际情况来调整落地。比如说依赖注入的方案,著名的开源项目中有 Angular 和 VsCode 都实现了依赖注入的框架,但并没有抽离出来直接可用的工具,我们可以通过研究它们的相关代码,分析其中的思路以及实现方式,然后在自己项目中使用。
3. 架构可拓展性
个人认为引入新架构或是新技术时,需要考虑两个很重要的点:
- 新架构/技术是否能支持业务的未来规划。
- 此次引入是否彻底,是否会留下新的技术债务。
不同的项目或是同一个项目的不同时期,关注的技术点都会不一样。在项目初期,关注重点往往是快速试错与功能迭代;在项目稳定期,项目的维护成本则会逐渐受到重视。
我们在引入新的技术或架构的时候,还需要考虑项目后续的发展规划。比如说我们在给项目引入依赖注入时,假设我们知道项目后续需要支持以应用中内嵌应用的功能,则可以考虑以 SDK 为维度来进行依赖注入,避免后续在同一个应用中存在两个 SDK 时,依赖注入管理混乱。
而技术变更会引入的技术债务问题,则还需要在方案设计的时候进行详细评估。举个例子,架构设计的改造,往往产生极大的工作量,面对这样的工作量是否有有效的解决方案,比如引入自动化流程进行、新增人力支援等。如果该问题无法有很好的解决方案,那么引入新技术必定会带来更多的技术债务,这种情况下就需要仔细衡量这个事情值不值得了。
至于技术方案调研相关,之前有写过一篇更详细的文章:《技术方案的调研和设计过程》,感兴趣的小伙伴也可以看看。
实际上,项目复盘也可以很好地解决剩余技术债务的问题,同时还能避免相同的错误再犯,之前《为什么项目复盘很重要》一文中也有介绍。
结束语
日子怎么过都是过,过得好过得坏也是一天天过,但稍微对自己有点要求和期待,日子可能会一天天变好呢~