此模式是 "遗留系统迁移模式" 的一部分

功能等效

使用新的技术栈复制现有遗留系统的功能。

2021 年 7 月 27 日

Ian CartwrightRob HornJames Lewis

在许多情况下,当我们与 IT 高管交谈时,我们听到他们如何拥有使用即将过时或已经过时的技术的套件老旧应用程序。更常见的是,这些系统托管在昂贵的第三方管理的数据中心中,并且具有不灵活的合同。这些应用程序对于业务的成功运营至关重要,同时也是业务和运营风险的最大来源之一。

他们都非常清楚,有机会进行改进,优化流程并释放新的机会。但是,要完全做到这一点将具有破坏性,并且会带来许多依赖关系。例如,现有“BAU”工作的承诺、其他变更计划,以及最终用户所在部门的现有计划和预算。

在这种情况下,一种方法是尝试通过“简单地”替换技术来最大程度地减少替换对更广泛组织的影响,同时将其他所有内容保持“原样”。这种方法通常被称为功能等效,或者被那些尝试过它的人称为“功能等效陷阱”。

虽然功能等效听起来像是一个合理的建议,但我们已经从痛苦的经历中了解到,人们严重低估了所需的工作量,因此误判了这种方法与其他替代方法之间的选择。例如,即使只是定义“现状”范围也可能是一项巨大的工作,尤其是对于已经成为业务核心的遗留系统而言。

大多数遗留系统随着时间的推移而“膨胀”,随着新功能的添加而没有删除旧功能,许多功能被用户未使用(根据 2014 年 Standish Group 报告,为 50%)。过去错误和限制的解决方法已成为当前业务流程的“必须具备”要求,用户的工作方式在很大程度上取决于遗留系统的限制,而不是其他任何因素。重建这些功能不仅是浪费,而且也错失了构建当今真正需要的功能的机会。这些系统通常是在 10 年或 20 年前在以前一代技术的限制下定义的,很少有意义“原样”复制它们。

如果功能等效是真正的要求,那么此模式描述了如何才能做好。这不是一条容易的路,也不是一条可以轻易走上的路。

工作原理

功能等效是一个简单的概念。构建一个新的系统,使用更合适的技术栈,具有与现有系统完全相同的功能和行为。每当有人问新系统应该做什么时,我们都会回答“做现有系统做的事情”。为了知道我们具有等效性,我们需要完全了解当前系统的工作原理,并且能够验证新系统确实做到了同样的事情。

范围是什么 - 旧系统做了什么?

功能等效的第一部分是创建一个关于当前系统工作原理的规范。可能需要以下组合:

系统调查

用户操作

用户角色是什么,他们可以看到系统中的哪些功能(菜单项),他们可以执行哪些操作。对于每个菜单项/操作 - 涉及哪些屏幕,哪些数据项,您可以看到哪些验证逻辑。用户执行操作后会有什么可观察的结果?

批处理

系统中定义了哪些批处理作业?它们何时触发,它们执行什么处理,有什么可观察的结果?

接口和集成

集成了哪些系统?

  • 此系统为其客户提供了哪些接口,这些合同是什么(API、CFR、行为期望/副作用)
  • 此系统消耗了哪些接口,这些合同是什么?
  • 注意通过数据库集成的系统或系统部分(请参阅报告/数据和考古学)
核心算法

需要复制的知名业务规则和计算 - 由用户操作、批处理触发。

报告/数据

系统创建了哪些报告,以什么格式,从哪些数据,何时以及多久一次?

数据如何在数据库中发生变异?是否有触发器更改数据,什么触发它们,以及它们触发了哪些过程?这个兔子洞有多深?

哪些其他系统可以访问或使用此数据进行集成?它们以什么方式更改它,以及这些更改有什么可观察的行为?

考古学

通常需要考古学才能完全了解系统的功能。通过“考古过程”,您了解到更改屏幕 A 上的数据字段 Y 会导致批处理作业 N 运行后报告 C 上出现值 Z。执行此考古学可能是对时间和那些对您的遗留系统最了解的人的脑力的重大投资。

仪器 - 基于数据,使用什么?

花一些时间分析现有报告(例如访问日志或其他系统日志)以了解当前系统的使用方式非常值得。如果这些不可用,那么对现有系统进行一些仪器投资可能会带来良好的回报,因为它可以让你避免基于数据进行不必要的工作。

功能价值 - 我们能放弃低价值的功能吗?

虽然我们试图避免在采用此模式时给企业带来负担,但与用户交谈以了解哪些功能价值较低或未使用可能有助于管理您的范围。但这将重新引入我们试图避免的组织影响/变更。

使用测试来确保功能等效 - 新系统做旧系统做的事情

了解旧系统的工作原理是第一个挑战,但我们还需要确保新系统确实以相同的方式工作。为了自信地验证这一点,我们需要进行测试来证明新系统确实具有功能等效性。以下是需要实施测试的领域列表。

用户旅程和用户体验

使用验收测试 - 检查您构建的功能是否按预期从用户的角度工作。注意不要依赖这些作为主要验证方法,因为它们位于测试金字塔的较高位置。此外,请注意,将系统分解为用户功能、屏幕和流程很容易导致过多的此类测试。

测试 UI 行为(包括客户端验证)相对容易:点击这里,期望看到一些状态,在那里输入数据,点击那里,期望看到一些不同的状态。使用适合您所选技术的工具 - SPA 应用程序的类似单元的测试框架,或者像 Cypress 这样的工具用于更传统的服务器端渲染应用程序。

在重要的位置(例如“专家用户优化”的 UI 中),测试布局(和外观/感觉)更难,但有一些工具可以提供帮助(例如,Galen 与 Selenium)。

对于可用性和布局,您可能依赖于探索性测试。

业务逻辑 - 核心算法

对于核心算法和核心业务逻辑,确保您围绕现有系统的这些部分构建了一套单元测试。这些将提供现有系统上已知成功运行的业务逻辑/算法的可执行规范。然后可以使用修改后的 TDD 方法,其中包括将这些测试移植到新的技术栈中,从而对新的实现充满信心。与知道您正确移植了测试相关联的风险 - 变异测试可以提供一些额外的保证 - 类似的变异在旧的和新的实现中会导致类似的失败。

接口 - 作为服务提供者和服务客户

作为服务提供者:创建一个测试套件来针对要替换的现有系统执行 - 一个可执行的合同。针对新的替换系统执行这些相同的测试,检查是否符合合同。注意不要让这些测试的范围变得太大,就像 UI 的情况一样。

作为客户:使用测试模拟来验证您是否以预期的方式与提供的服务进行交互。与核心业务逻辑一样,将这些模拟迁移到新的技术栈中,以确保新的实现继续以相同的方式与提供的系统进行交互。此外,使用外部系统的存根来为您的新测试提供已知的数据集。

在这两种情况下:代理都是一个有用的工具,可以确保功能/交互等效性。通过将代理注入通信路径,可以记录与旧系统的交互。您可以使用这些记录来

  • 重放来自客户的消息 - 并检查新系统的响应
  • 创建可以重放已知良好响应的存根

数据库和报告:这可能非常困难 - 就像 UI 测试一样,注意金字塔的顶部。这里的数据库/报告是另一种类型的接口。成功测试它们将需要大量测试数据 - 通常难以创建/管理。

实施和跟踪进度

完成系统调查以定义范围,并有一套全面的测试来提供行为的可执行规范,您的实现就可以相对自信地进行。但是如何跟踪进度?

按菜单项/用户操作

(或在调查系统时识别的其他部分)这可能很危险,因为存在您跟踪的内容可能会按层(或架构关注点)切片的风险。按架构层切片会严重影响价值交付,并降低进度可见性。(即,在功能从上到下交付之前,不会解锁任何价值,也不会取得任何_真正的_进展)。

这里的一个关键假设是,项目或操作本身可以为最终用户提供价值。不幸的是,情况往往并非如此,我们可能会交付 80% 的单个流程步骤,但仍然无法在新系统中完成整个业务流程。这是一种不幸的常见情况,报告了很高的完成度,但无法测试或发布可用的软件。

垂直切片

提供更好的进度透明度,但垂直切片可能不是系统调查的输出。因此,必须进行映射 - 更多工作,以及需求掉入空白处的风险。

端到端流程

根据将单个业务流程完全迁移到新解决方案的进度进行跟踪,因此测试变为:是否可以在替换系统中完全完成流程。这可以与上面按用户操作进行跟踪相结合,但前提是我们确保为交付单个流程步骤所做的工作按“拥有”业务流程进行优先级排序。

作者希望确保任何工作的完成定义都包含(尽可能)跨所有层的完整端到端范围。

何时使用它

我们已经在上面介绍了我们对如何很好地应用这种模式以及提高成功率的看法。如果目标是功能一致性,那么确定功能方面需要什么将涉及大量工作,而确保通过测试满足功能一致性目标将涉及更多工作。

总的来说,我们不推荐这种模式。事实上,Thoughtworks 甚至将这种模式列入了我们的技术雷达的暂停状态。我们认为这种模式错失了巨大的机会。旧系统通常会随着时间的推移而膨胀,许多功能未被用户使用(根据 2014 年 Standish Group 的报告,比例高达 50%),并且业务流程也随着时间的推移而演变。替换这些功能是一种浪费。相反,尝试集中精力退一步,了解用户当前的需求,并根据业务成果和指标对这些需求进行优先排序。

然而,我们已经看到了一些特别适合应用这种模式的案例。

  • 针对高级用户的经过高度优化的用户界面 是进行逐一复制的理想选择。例如,考虑使用快捷键以高速执行交易的代理。为了有效地完成工作,他们可能需要高度优化的用户界面,使他们能够仅使用键盘进行操作。可能需要大量时间才能熟练掌握,并且会导致效率降低的更改是不可接受的。
  • 基于知名规范的行为: 应用这种模式的另一个用例可能是支持工程或科学建模的系统。例如,在有限元分析求解器的情况下,给定的输入应该产生给定的输出 - 物理定律不会随着现代化项目的进行而改变。

有人可能会争辩说,在这两种情况下,对功能一致性的需求都是某种程度上局部的 - 我的意思是限制在系统的特定部分。将整个系统现代化的范围管理方法是否受限于这些局部用例值得怀疑。

但是,这些案例虽然有效,但仍然是例外。我们绝大多数情况下看到的功能一致性练习都是令人沮丧的。正确理解现有功能所需的成本和工作量会激增,导致偷工减料,尽管其中一些是应该被裁减的未被使用的功能,但通常一些重要功能也会受到影响。如果一切顺利,企业会花一大笔钱,却无法改善对企业的支持。当企业知道他们的未来取决于更好的技术参与时,这不是一个好故事。

替代方法

  • 提取产品线 或提取价值流都是提供识别现有系统中薄切片的策略的模式。其中一个关键区别在于,它们都提供了缩短反馈周期的途径,同时允许更快地禁用和关闭遗留元素。
  • 关注业务价值并确保它在任何架构决策中得到体现,通常可以突出显示功能一致性驱动方法的问题。
  • 更“整体”的方法可以通过将技术和业务流程视为同一个问题的一部分来帮助突出显示功能一致性的问题。特别是在功能一致性的情况下,这通常可以突出显示当前的业务流程是遗留技术所需的工作区和妥协的结果。仅仅替换技术将无法解决至少一半的问题。
  • 用户研究可以帮助突出显示现有的业务流程不再适合目的。在一个案例中,仅仅通过对现有员工进行几天的跟踪,就清楚地表明功能一致性不适合,因为当前的流程非常糟糕,与最终用户交谈总是一件好事。

示例:物流系统替换

一家物流公司正在进行一项计划,以替换用于包裹验收、路线规划和交付的过时软件。作为这项计划的一部分,他们同意了一项由 IT 主导的计划,与业务利益相关者的参与度相对较低。技术观点认为,他们可以简单地进行“功能一致性”,从而解决他们迫切需要替换过时技术的需要。作为这项计划的一部分,他们完成了一项主要工作,以替换从客户处接收包裹的系统。我们在该计划的最后阶段参与进来。

我们认为,与业务利益相关者的低参与度对该计划构成风险,特别是因为我们从另一个项目中听说,企业对开发工作感到沮丧。作为这项工作的一部分,我们与关键利益相关者(包括财务团队)进行了交谈。正是在这个时候,我们意识到他们进行了一项审查,该审查表明只有相对较小比例的客户对公司有利可图。反过来,这意味着只有很小一部分“包裹类型”是有利可图的,许多包裹由于特殊处理要求而给公司带来了损失。因此,企业制定了一项计划,停止处理这些包裹。

事实证明,“功能一致性”项目中投入了大量精力来处理这些包裹,而这些包裹正是企业表示不再需要的包裹。企业希望在没有这些困难的边缘案例的情况下,流程和软件会变得更加简单。在这种情况下,“功能一致性”导致花费了大量时间和金钱来处理企业不再需要的需求,同时进一步损害了 IT 在企业眼中的声誉。

示例:电子商务组织重新平台化

这家公司经历了一段快速增长时期,但多年来没有优先考虑 IT 支出,这造成了替换当前解决方案的许多元素的相对紧迫需求。例如,在某些时期,他们不得不放慢销售速度,以避免压垮核心系统,从商业角度来看,这绝非理想。

许多关键业务运营由同一个大型机处理,该大型机最初是在他们电子商务运营的早期阶段投入使用的。从该系统中提取元素显然在技术上具有挑战性。与此同时,业务领导者在经历了几个破坏性的失败项目后,希望将对员工的任何进一步干扰降至最低。另一个挑战是,当前的流程和系统使得在使用更渐进的方法时,很难对要迁移的产品线进行优先排序。简而言之,很难理解他们销售的哪些东西有利可图,哪些东西没有利可图,因此人们认为唯一的选择是一次性迁移所有内容。基于这些挑战,人们认为仅仅复制他们所拥有的东西是最佳且风险最低的方法。

鉴于当前的业务流程表面上都是一起在同一个大型机中实施的,这意味着任何“功能一致性”替换的范围本质上是整个企业的所有主要活动和流程。他们开始努力记录替换系统的“范围内”现状流程,计划将其用作供应商选择流程的输入。

很快就有几件事变得很清楚。其中之一是,它实际上必须几乎涵盖企业所做的每一项活动,每一次记录“现状”功能的努力都会发现更多需要包含在内以实现“功能一致性”的内容。其次,由于历史上的工作区、多年来不断变化的需求以及许多未解决的错误,实际使用遗留系统的人员最不希望看到的是相同的东西。它几乎总是使他们的工作更加困难,并且是错误和延迟的主要来源。最后,由于错误和工作区,很明显,一些关键流程实际上是在手工构建的电子表格上“离系统”运行的。关键业务数据从大型机中提取出来,用于通过电子表格运行业务流程,然后稍后将修改后的数据上传回大型机。

此时,有些人认为“功能一致性”正在变得过于冒险,范围不断扩大。这是在需求收集过程完成之前,并且该过程没有明确的结束日期。我们的参与在这个阶段停止了,因为我们认为继续进行“功能一致性”风险太大,并且无法提供企业所需的成果,尤其是由于缺乏关键业务指标,使得无法对任何更渐进的方法进行优先排序。几年后,他们仍在进行“现状”需求流程,远远超过了最初的截止日期。

缺乏合适的指标和无法从业务角度对功能元素进行优先排序,通常会迫使企业采用“功能一致性”方法。在这种情况下,我们认为,最初努力收集围绕各种产品线的关键业务指标可能已经提出了分解问题的方法。这是一个很好的例子,说明在没有合适的业务背景和参与的情况下,你无法做出正确的技术决策。

示例:成功替换金融计算服务

我们的一支团队正在为一家大型金融机构工作。他们希望对一个执行复杂财务计算的现有服务进行现代化改造。财务计算的规范是固定的,服务的接口是相似的,只是需要更新技术 - 从 J2EE Session EJB 实现更新到最新(当时)版本的 Java 中的 SOAP Web 服务。

该团队围绕现有实现创建了一个丰富的测试套件,在设置、执行和断言职责之间进行了清晰的隔离。

图 1:功能一致性测试

一旦测试到位,就可以以最小的风险替换执行适配器,并创建一个新的实现,满足与旧系统相同的可执行规范。

重大修订

2021 年 7 月 27 日