在最近几年里,几乎没有全新的系统开发工作了,不是在修修补补就是对遗留系统进行改造,让其重新适应业务发展的需要。我参与过类似于遗留系统的改造有:

  • 一个长期演进的大单体,人员规模增长,业务需求变得愈加复杂,我们不得不对其服务化。
  • 一个已经运行了几十年的业务系统,无论是编程语言还是框架都不在能跟上现在的技术趋势,添加新的功能变得愈来愈复杂,相关的依赖包也没人在维护,甚至相关技术栈的开发人员都很难在市面上找到。
  • 一个庞大系统中的一个组件,已经运行了很多年,因为某些原因(性能、安全)需要开发新的并将其替换掉。

在讨论后面的内容之前,我不知道这些是否从严格意义上来说是遗留系统,也不知道我的工作是重构或者重写。由于今天我们不得不面对一个问题,对于很难维护的系统,我们如何合理的决策,对其重构还是重写。

01 什么是遗留系统?

我找到了一些关于遗留系统的权威定义。

国际标准化组织(ISO): ISO/IEC/IEEE 24765:2010 将遗留系统定义为“旧的方法、技术、计算机系统或应用程序,尽管有更新的技术或更高效的方法可供使用,但由于仍能满足用户需求而继续使用。”

根据IEEE,遗留系统是“依赖于过时或淘汰技术的系统,但仍对组织的运营至关重要。”

我识别到有两个关键要素:过时或者淘汰的技术,仍然需要继续使用和满足运营需要。

所以遗留系统的问题在于 “业务需求和技术过时直接的矛盾”。没有持续盈利的业务需要,也就没有改造遗留系统的意义了。所以非常有意思的是,虽然遗留系统被广大程序员避之不及,但遗留系统改造工作具有广大的市场空间。

02 重构和重写的差异

在《重构》一书中, Martin Flower 对“重构”的理解是: 重构的对象是代码,工作在系统的内部,并不改变系统或者组件的外部行为,另外重构是一个持续的过程。

我们尝试给重写一个定义: 重写的对象往往是系统或者完整的组件,可能会导致相关接口升级或者修改,甚至在重写的过程中,会增加新的特性,或者废弃部分功能。

下面我整理了一个清单,对比这两者的差异,用于后续决策的考量:

重构重写
工作目标改善代码结构、可读性、可维护性和性能采用新技术或架构,解决旧系统中的根本问题
时间短期内见效,逐步改进需要特别规划一个项目或者特定周期
影响对上下游系统影响较小,几乎对其透明往往需要协同切换,甚至做停服割接业务
工作对象代码系统或者组件
成本
风险
收益持续提高代码可维护性一次性解决系统设计的本质问题

03 决策的考量?

我们的客户经常会为重构还是重写做出选择而头疼,这里尝试整理了一个参考问题清单,根据问题的结论作为决策参考。

  1. 使用的编程语言是否为当前企业的主要选择?
  2. 使用的框架是否已经过时,并难以升级到新的框架中来?
  3. 使用的依赖库是否还在被更新,或者能找到替换选项,并很容易被替换?
  4. 投资是否能支持完成重写计划?
  5. 团队人员能否在持续维护现有系统的情况下,仍然有能力开发新的系统?
  6. 是否存在重大的安全威胁,且无法通过重构实现?
  7. 是否有政策合规的影响,且无法通过重构实现?例如国家信创战略等要求等。

补充问题,如何让领导对重写买单?

  1. 假设系统将被重写,是否会有新的功能被加入进来?
  2. 重写后能否估算出增加新的功能可以减少多少工作量?

从上述的问题清单中,有两个启示:

  1. 技术决策背后往往会掺杂利益问题和价值判断。从业务方的角度来说,需要对比的是持续重构带来的成本和一次性投资重写的成本,这两者带来的成效哪一个更高?而对于技术人员来说,维护的便利性是优先考虑的要素,因为难以维护的项目可能会带来更多的而线上 Bug 和安全事件。
  2. 在众多考量点中,某些考量是决定性的。这些决定性的考量往往和公司业务有关,例如对于银行来说,安全和政策合规是第一要素,如果系统持续重构无法解决安全和政策合规问题,那么即使不得不加大投资,也能接受系统被重写;而对于互联网公司来说,除了安全和政策合规外,快速响应业务变更也很重要,因此对于重写更加积极。

04 相关的教训

  • 了解遗留系统中的隐藏规则是巨大的挑战之一。
  • 遗留系统比新系统有更多的熵,因此不应该照抄遗留系统的业务逻辑进行重写,而应该重新设计。
  • 遗留系统的工作量远远大于新建一个系统,因此在估算上需要特别考虑兼容和切换成本。
  • 团队在重写的过程中,需要仍然维护遗留系统并添加新的功能,这个阶段会导致团队压力非常大。

参考资料

  • https://juejin.cn/post/6844903892828831757
  • https://www.infoq.com/news/2009/11/refactor-rewrite/
Last Updated:
Contributors: linksgo2011