旧版代码是指仍在发挥作用,但使用旧版技术开发的软件代码。它包括从其他团队或旧软件版本继承的代码,以及不再受到积极支持或维护的源代码。它还包括使用过时的硬件或操作系统、已被淘汰的编译器或应用程序编程接口 (API),或过时的编程语言或软件开发环境所编写的代码。旧版代码已不再符合新的编码标准、当前的软件设计原则或最新的计算架构。
在 2004 年出版的《Working Effectively with Legacy Code》一书中,Michael Feathers 提出了另一种说法,即“没有测试的代码”。1这种旧版代码的定义意味着程序员无法验证代码是否有效以及是否能达到预期效果。许多旧版系统也缺乏对理解其行为至关重要的足够文档,这使得扩展或增强这些系统对开发人员来说成为一项艰巨的任务。
由于其过时的特性,旧版代码可能无法与更现代的系统兼容或难以整合。缺乏适应性可能会阻碍创新并减缓业务增长,进而使企业失去竞争优势。
旧版系统的维护成本可能很高。这些运营和维护成本可能会增加,而旧版软件和硬件的第三方支持费用也会随之增加。此外,寻找精通陈旧计算实践或编程语言的开发人员极具挑战性,而且需要付出代价。
繁杂的单体架构会导致高延迟、响应时间慢和频繁停机时间。性能迟滞会对用户体验造成负面影响,并降低客户满意度。它还会影响使用和维护这些系统的团队成员的生产力及效率。
过时的系统会因用户负载不断增加而受到影响。它们难以满足激增的需求,也无法按需增减规模。组件紧密耦合,也使其难以升级现有功能或添加新功能。
旧代码可能并未主动更新安全补丁并遵循最新的安全标准,因此容易遭受网络攻击和入侵。旧版系统也可能不符合现行法规。
第一步是了解代码库,这通常也是最困难的部分。首先要查看任何可用的文档,无论是需求文档、内联代码注释还是版本控制历史记录(如提交日志或更改日志)。
当文档不足时,可尝试使用静态代码分析工具,该工具无需运行即可自动检查代码。此外,代码可视化工具可以创建源代码结构的图形表示,从而描绘元素之间的依赖关系和交互关系。
一旦软件开发团队对旧版系统有了足够的了解,就能着手加以处理。这些庞大的代码库可能令人毫无头绪,因此需将其划分为更小、更易于管理的模块,以便一次处理一个模块。
测试通常用于验证代码及其预期行为的准确性。但是,创建特征测试是为了理解代码的作用和功能。这对于理解旧版代码大有帮助。2
企业在实现旧版代码的现代化时通常有 3 个选择:重构、迁移或重写。他们也可以将这些方法中的任何一种结合起来。决定走哪条路需要软件工程团队和业务领导团队的共同参与。
代码重构会改变源代码的内部结构,而不修改其外部行为或影响其功能。这些细微的更改不太可能引入错误,但能生成更易于维护且清晰、简洁的代码。
对于旧版代码,团队可以从每个模块的细微修改入手,包括重命名变量、删除重复或未使用的方法以及标准化格式。然后,他们可以执行更多基于逻辑的重构任务,例如将大型方法分解为较小的方法、简化复杂条件以及在函数之间移动功能,以减少其依赖性并增强内聚性。
迁移是实现旧版代码现代化的另一种途径。这需要将全部或部分代码迁移到更新的平台或技术堆栈,例如从单片架构过渡到微服务或从本地迁移到云。重点是要检查与平台或技术堆栈的兼容性,并确认供应商是否在迁移过程中提供任何支持。
重写旧版代码往往是最后的选择,因为这涉及创建全新代码来取代旧代码。这本身就是一个新项目,是一项艰巨的任务,可能需要一个单独的开发团队来处理。
对于庞大的旧版代码库来说,迁移和重写都是艰巨的任务,因此团队可以考虑采用“绞杀榕”战略。3绞杀榕生长于树木表面的高处,其根系一直延伸到地面,慢慢地将寄生树木包裹在收缩状格栅中,最终使其枯萎。
就旧版系统而言,团队可以逐步迁移或重写微小的代码片段,直至整个代码库切换到现代框架或使用当前编程语言进行开发。但是,团队必须构建过渡架构,确保现有代码和新代码能够共存。一旦迁移或重写工作完成,这一过渡架构就将停用。3
彻底测试重构、迁移或重写的代码,确保不会出现错误,这一点至关重要。开发人员可以编写专属整合和单元测试,但还需要让 QA 团队参与进来,执行运行功能、回归和端到端测试来检查功能及行为是否完好无损。
文档记录是现代化工作流的另一个关键部分。记录源代码更改,无论是通过内联注释注释源代码、创建详细的更改日志还是编写全面的架构和设计文档以及其他技术文档。
有几种工具可以帮助加快和自动化旧版代码的现代化过程。以下是一些常见的工具:
● 静态代码分析器
● 代码可视化应用程序
● 测试自动化框架
● 迁移平台和工具包
● 文档生成器
代码可视化工具以图形方式表示源代码,帮助开发人员了解其运作方式,特别是针对大型或复杂的代码库。这些图形表示有不同的格式,例如代码图、流程图和统一建模语言 (UML) 图。代码可视化应用程序的示例包括 CodeScene、Code See 和 Understanding 等。
这些框架可创建和运行自动化测试,并生成测试报告。热门测试自动化框架包括用于 Web 应用程序的 Cypress 和 Selenium 以及用于移动应用程序的 Appium。
这些平台和工具包有助于简化和自动迁移旧版系统工作流。部分主要迁移平台包括 AWS Application Migration Service、Azure Migrate、Google Cloud 迁移工具包、IBM Cloud Transformation Advisor 和 Red Hat Migration Toolkit for Applications。
这些工具可根据源代码和其他输入文件自动生成文档。文档生成工具的示例包括 Doxygen、Sphinx 和 Swimm 等。
人工智能 (AI) 可以协助旧版代码现代化进程。生成式 AI 应用程序由大型语言模型 (LLM) 提供支持,这些模型可以分析复杂或庞大的旧版代码库。
生成式 AI 可用于协助完成以下旧版代码现代化任务:
● 代码解释
● 代码重构
● 代码转换
● 测试生成和文档记录
生成式 AI 可以理解支持旧版代码库的上下文和语义。这使它们能够概述其背后的逻辑和功能,以程序员可以理解的方式解释代码。
人工智能驱动工具可以提供实时重构建议。例如,IBM® watsonx Code Assistant 可利用 IBM® Granite 模型来识别错误并进行优化。然后,它会根据团队既定的编码规范提出有针对性的修复建议,从而简化和加速代码重构。
与测试自动化框架一样,AI 编码助手也能自动生成测试。此外,它们还可以创建内联注释,以记录某些代码段或代码片段的功能。
与任何人工智能驱动的应用程序一样,程序员在使用 AI 对旧版代码进行现代化改造时仍须谨慎行事。他们必须检查输出的准确性,并测试任何建议的更改或修复。
Instana 通过提供全面的监控和切实可行的洞察分析,简化企业的云迁移之旅。
利用生成式 AI 加速和简化大型机应用程序的现代化。
利用混合云和人工智能驱动的现代化服务和策略优化旧版应用程序。
1 #195 - 使用旧版代码和 AI 编码助手有效工作 - Michael Feathers,Tech Lead Journal,2024 年 10 月 14 日
2 特征测试,Michael Feathers,2016 年 8 月 8 日
3 “Strangler Fig”,Martin Fowler,2024 年 8 月 22 日