在快速发展的业务推动下,技术债务的积累成为技术团队难以回避的挑战。如何系统性地偿还技术债务,并从治理过程中提炼宝贵经验,是值得深入探讨的重要课题。
此前,《聊一下,技术债务治理》一文已对技术债务的背景、分类及治理思路进行了全面概述,而《从技术债务到架构升级,滴滴国际化外卖的变革》则聚焦于业务营销场景,探讨了如何通过配置模型、优化表单、引入安全校验等手段提升开发效率。
作为“技术债务治理”专题的收官之作,本文将深入剖析国际化外卖骑手侧H5项目(以下简称DH5)的治理实践。从技术债务的产生根源,到问题的拆解与分析,再到具体的解决方案及最终成果,我们将全方位总结DH5项目的治理经验,为类似场景下的项目治理提供参考与借鉴。
项目背景:技术债是怎么欠下的?
项目历史演进
DH5项目涵盖了国际化D端业务除接单主流程外的80%页面,主要分为以下三大业务模块:运营、管控和财务。
最初,这三大业务模块都集中在一个前端项目中(all-in-one-i18n),但随着业务的扩展,问题开始显现:维护困难、环境冲突和研发体验差。
为了解决这些问题,我们将项目拆分为三个独立的前端项目:op运营、govern管控和fund财务。
项目拆分后的技术债现状
项目拆分为了三个独立项目,具体结构如下图所示:
业务模块:项目承接的业务模块;
公共组件:项目代码中承担高频率出现有业务性质的组件;
公共方法:项目代码中处理移动端每个模块都需要的公共方法,包括网络请求,数据埋点,端通信bridge,用户登录和获取公参数等;
开发工具:开发过程中与业务无关的提高开发和调试效率的工具。
项目拆分虽实现了业务独立和上线流程的独立,但拆分过程及多年业务迭代所积累的技术债务也随之显现:
业务模块:存在业务迭代过程中已弃用的业务模块;
公共组件:拆分时部分项目不使用的组件也被迁移到新的项目中,形成冗余;
公共方法:存在同一功能多种写法,拓展性差,增加维护成本;
调试工具:功能不完善,在调试生产环境和环境切换时存在困难。
问题拆解:要解决的技术债有哪些?
将上面的技术债进行分类可以分为两大类:冗余代码类和代码缺陷类。
冗余代码类问题
冗余代码类问题由上面具体问题可以看出来主要分成两种:
代码缺陷类问题
代码缺陷类涵盖内容比较广泛,包括设计缺陷和功能缺陷等。本次DH5项目中的公共方法缺陷主要是设计缺陷,调试工具缺陷主要是功能缺陷。下面会对具体问题具体分析。
公共方法缺陷
公共方法缺陷的主要问题是公共方法一个功能存在多个版本,需要解决的问题如下:
拓展性不足:历史代码设计时未考虑后续需求,导致开发新功能时需要额外创建新版本。
文档不充分:缺乏统一文档,新人开发时难以判断选择哪个版本。
调试工具方法缺陷
调试工具缺陷的主要问题是调试工具在使用过程中不贴合具体使用场景,具体问题为:
线上调试困难:生产环境中缺乏调试工具,无法快速定位问题。
环境切换问题:在客户端切换DH5环境需要代理工具辅助,效率低下。
解决方案:逐个偿还技术债
通过以上的分析得到了DH5具体的技术债,最终希望偿还技术债的结果如下:
1.删除冗余代码,包括未引用代码和弃用业务模块;
2.解决代码缺陷问题:
消除多个版本公共方法,即公共方法标准化,在DH5落地并产出相应文档;
调试工具功能完善,包括线上调试功能和环境切换功能。
总体解决流程
技术债偿还的过程是环环相扣的:
删除冗余代码:为后续公共方法的改造扫清障碍;
公共方法标准化:制定新方案,确保业务功能覆盖与可拓展性;
调试工具完善:提供工具支持,为冗余代码删除和标准化方法落地提供支持,提升开发和调试效率。
冗余代码清理
清除未引用和业务弃用的代码,保证不产生新的冗余代码
关键点:
清理彻底:未引用和业务弃用的代码都需要清除;
不产生新冗余代码:保证删除冗余代码不产生新的未被引用代码。
为了保障这两点,需要在每次删除一批冗余代码后,重新分析代码依赖关系,即循环检测,避免遗漏新产生的冗余代码形成新的技术债。主要实施流程如下:
代码缺陷问题解决
公共方法标准化
公共方法标准化,即是提供一个达成共识的移动端通用公共方法的标准化方案。主要解决步骤可以拆解成方案设计和方案落地两部分。
方案设计
关键点:
功能全:保证新方法能支持所有历史功能;
可拓展:保证未来新增功能无需再开发新版本。
为了保障这两点方案设计流程如下:
方案落地
关键点:
稳定性:保证业务稳定性;
替换彻底:公共方法替换彻底不产生新的技术债。
为了保障稳定性和替换彻底两点要求,方案落地做了严格的流程管理,共分为四个阶段进行落地:
第一阶段:确保公共方法代码功能上的可用性
验证功能可用性:通过功能测试确保公共方法在不同模块中的可用性,避免在不同业务中出现兼容性问题;
完善文档:确保文档不仅包括函数功能说明,还涵盖了如何接入和使用的具体步骤,特别是对新手的引导。可以考虑为文档增加示例代码和常见错误排查指南。
第二阶段:将业务模块拆分成最小单元
拆分策略:通过模块化设计,将复杂业务拆解为独立的最小单元,使得每个单元都可以独立进行测试、上线;
影响范围梳理:在每次接入公共方法时,需全面梳理模块间的依赖关系,确保对其他模块的影响最小。
第三阶段:代码功能测试和业务功能测试
研发自测与交叉测试:在QA资源有限的情况下,交叉测试是一种有效的方式,确保每个开发人员不仅关注自己开发的模块,还能从其他角度发现潜在问题;
上线监控:设置全面的监控系统,确保当公共方法出现问题时可以即时发现并处理。结合业务指标监控与代码报错监控,做到问题及时响应。
第四阶段:彻底替换旧公共方法
查漏补缺:确保没有遗漏仍在使用旧公共方法的地方。并且,在旧方法彻底删除后,确保没有遗留冗余代码;
冗余代码清理:定期执行冗余代码扫描,并建立清理机制,避免未来再次出现相似问题。
调试工具
调试工具的问题主要集中在两点:线上调试困难和环境切换问题。
线上调试困难
移动端调试工具使用的是vconsole,但是仅在development环境展示该工具,现在修改为在sim环境和APP的debug包中展示,具体如下图:
环境切换问题
基于 vConsole 的插件能力,新增环境切换 Tab,简化开发流程。
成果-技术债偿还情况
代码缺陷问题解决
公共方法标准化
调试工具
线上调试新增工具:新增pre和online环境在debug包中展示调试工具,解决了线上问题调试难的问题;
环境切换工具产出:产出调试工具不再依赖代理工具切换环境,缩短在客户端的H5页面调试线路。
心得体会
随着业务的快速发展,技术债的积累几乎是不可避免的。然而,通过系统性地进行技术债治理,我们不仅有效提升了代码质量,也为团队提供了宝贵的经验和实践积累。治理技术债是一项复杂且长期的系统工程,贯穿了多个层面的优化:
冗余代码清理是治理的基础。通过全面的代码审查和重构,我们剔除了不必要的冗余代码,减少了系统的复杂度,为后续的优化和扩展提供了更加稳定的基础。
公共方法的标准化是治理的核心。我们统一了大组内部的公共方法,避免了各小组重复造轮子,提升了开发效率,确保了团队在不同模块之间的协同工作更加顺畅。这一标准化成果不仅解决了小组内部的问题,更为整个大组提供了共享的解决方案,确保了跨团队的一致性和可维护性。
调试工具的完善为开发和运维提供了有力的支持。通过引入和优化调试工具,我们显著提升了问题定位和解决的效率,使得开发人员可以更加高效地发现并解决潜在的问题。
这三者相辅相成,缺一不可。冗余代码清理为后续的标准化和工具完善奠定了基础,标准化公共方法则提升了团队协作的效率,而调试工具的优化进一步提升了开发人员的工作效率。
协作至关重要:治理过程中,跨小组的协作是成功的关键。在整个过程中,团队成员积极沟通、共同参与,确保了每个环节的细节都能得到充分考虑,并通过集体智慧不断完善方案。最终,我们不仅解决了局部问题,更推动了大组整体的技术进步,达成了项目治理的长期目标。
通过此次技术债治理,我们取得了显著的进展,不仅优化了代码质量,还为团队提供了持续的技术积累和经验教训。这一过程的成功实施将成为未来开发流程中重要的参考,并为团队的技术迭代提供坚实的保障。