技术债务和设计死亡

第一部分

 在最近的一次Scrum聚会上,Ken Schwaber 和Jeff Sutherland谈到技术和设计的死亡。虽然这两个概念本身不是新的,Ken和Jeff发现的关于它们的许多特征(我认为)属于独创而深刻的见解。此外,他们还概述了一些有用的图表,公司或部门可以用它来显示软件产品的“健康”状况。我本来打算写一篇文章,讨论这些图表指示的含义以及图表所需的数据。不过,我想为此引用说明Ken和Jeff观点的文章。搜索了网络,我却没有找到什么。最后我决定,既写介绍,也写后续的文章。这第一篇文章是介绍,讨论了技术债务、设计死亡的概念,及其最主要的特点。

 积累债务

 在项目过程中,一个组织很容易在软件质量上变得马虎。原因可能有很多:最主要的是团队在给定的时间内被期望完成太多功能;或者质量不被认为是软件高优先级考虑的特征。

 让我们考虑一个虚构出来的“典型”项目团队的例子,该团队正在进行公司旗舰产品的开发工作(见图1)。假设他们并没有取得最初预计的进展(见图2)。

scrum1234

 

图1:项目最初的预计。

 scrumwertd

 

 

 

 

 

图2:现实有办法让我们知道它的存在!

 

高级管理人员想知道团队为什么没有达到预期的进展。无形的压力开始施加,以使项目按时完成(见图3)。对于新的时间表,项目经理解释说,“团队已经学会了更高效率地工作” 。事实上这不是真的。为了按时发布,团队降低了软件的质量。团队实际交付的软件和本来应该交付的软件之间的差别,就是我们所知道的技术债务(见图4)。

scrum3451

 

 

 

图3:项目团队被施加压力,以“更有效率”。

scrumsdtewq3

 

 

 

图4:技术债务。

 scrumwqeg3

现在让我们考虑搭建在相同代码基底上另一个项目。对于按时交付,同样的问题仍然存在。但这次他们还有一个额外的劣势,就是在劣质的代码基底上工作。他们的进展比第一个团队更慢。上一次运作得非常好的管理技术将再一次被使用,压力再次施加到项目团队身上。他们 最终“按时并在预算内” 完成了项目,但远不如第一个团队“有效率”。现在的情况等于是在一层cruft建造了另一层cruft(见图5)。

 

Cruft(n):1)一种让人不愉快的物质。在你的床底下聚集的灰尘是cruft;TMRC词典正确注释说“用扫帚对付,只会产生更多”。 2)劣质建造的结果。——术语文件4.2.0

 

 

 

 

图5:cruft之上的cruft。

 

Cruft的严重情形

 

软件复杂性的债务概念最初是由Ward Cunningham在一份OOPSLA ’92的经验报告中提出的。自此它赢得了大批追随者,并扩展到包含了技术债务和设计债务以及一些其他观念。

 

技术债务就是被耽延的工作,与新功能没有直接关系,但对系统的整体质量有影响。这方面的例子包括推迟必要的工具和框架的升级,拖延过度复杂的系统组成部分的重构,等等。如果这个技术工作对系统的健康是必要的,那么长期忽略它会发生什么呢?当存在了若干层cruft,却没有单元测试帮助重构,又会任何呢?

 设计死亡

 时间快进两年;该公司的旗舰产品现在已是第四个版本。较比最初,它在范围上大大扩展,并且变得非常非常复杂。事实上太过复杂了,它的部分代码在全公司只有一两个开发人员有能力作改动。它的类可能有几千行代码。

 真实的故事:最近与一些形容他们的类非常复杂的客户交谈。我问他们:“你们的类多长?三、四千行吗?”客户们突然都大笑起来。我很困惑,问是什么这么有趣。“如果我们的类只有三千或四千行,我们就太幸运了……还要再加上1万行呢!”

 当代码到达这种债务水平,改变代码的任何一部分的所需努力都是非常重大的。对于所有的意图和目的,代码可被描述为设计死亡。Ken发现了进入设计死亡代码的三个属性:

 1. 该代码被认为是核心或遗留系统的一部分。在功能上与太多系统的其他部分相互联系,以至于分离(从而减少)任何一个组成部分都是不可能的。

 2. 在代码周围要么没有测试,要么只有极小的测试。如果没有全面的单元测试,重构代码从而达到一个更容易管理的状态是不可能的。

3. 关于核心和遗留系统,有高度区分的知识,而公司里可能只有一、两个人能支持。

 生命补给

 了解所有这些信息都非常有意思,但它如何帮助公司呢?它如何帮助有大量遗留系统的公司呢?有哪些备选办法可以为他们提供?这是我最初着手讨论的主题,现在将在第二部分中讲述。

 第二部分

 上一篇文章谈到了技术债务和设计死亡的问题。这篇文章将在它的基础上进一步扩展。我想用一种远离学术的方式,讨论一旦已有遗留代码会发生什么。对处理这个问题你有哪些可选择的方法?什么才是真正无法挽回的地步?

 遗留系统

 遗留系统(n):因为更换或重新设计花费较大,在竞争力与兼容性与最新等值的相比较差、却仍被继续使用的计算机系统或应用程序。这意味着该系统是庞大、整块且难以修改的。

 如果遗留软件只能在过时的硬件上运行,维护成本最终可能超过同时更换软件和硬件的花费,除非某种形式的仿真或向后兼容允许该软件运行于新硬件。——免费的在线计算机词典

 任何一个比较大的银行或保险公司都将拥有众多的遗留系统,其中许多是“绿屏”(即连接到IBM主机上运行一些Cobol数据库应用程序的哑终端)。仅在美国就有数以百计的银行。甚至相对年轻的公司(不到20年)也会有遗留系统,虽然他们经常使用“核心core”而不是“遗留legacy”来描述它。

 任何使用这些遗留(或核心)应用程序工作的人将认同Ken Schwaber提出的设计死亡的特点,我在第一部分已概述过。这里再简要重复一下:

1. 该代码被认为是核心或遗留系统的一部分。

2. 在代码周围要么没有测试,要么只有极小的测试。

3. 关于核心和遗留系统,有高度划分的知识,而公司里可能只有一、两个人能支持它。

我想再补充一个额外的特点,那就是:

4. 遗留系统不处在一个可知的状态。

 关于第四点,我的意思在任何指定的时间及时确定系统状态可能很困难(如果不是完全不可能的话)。安装系统以及失败后重启,往往被认为是某种形式的魔术。

 熵是从热力学中借用的术语,应用于软件,它可被看作是测量混乱的一种标准。软件的熵来自于对代码库的修改,如错误修复、对现有功能的升级以及新功能的增加。一段时间以后,这些小的变化累积起来,可能使得一个系统与外部系统连接过多,并且在功能上没有明确的轮廓,从而使系统很难再改变了。

 竞争降低了现有软件的价值。为了保持竞争力,企业必须不断地增加新的功能,只是为了保持现有软件的价值。关于这一点,我曾打算叙述一个虚构的故事来说明它是如何发生的,但后来我碰到了一篇描述这方面真实情况的文章。这篇文章远比我更好地表明了竞争的无情本质。

 为了保持有价值,软件(或该软件提供的服务)需要不断增值。这意味着,为了保持有价值,软件需要不断地改变(即升级)。但是这种改变的行为增加了系统的熵——从而提高了改变的成本。

 在过去6个月里,我至少跟三个正计划从头开始重写他们系统的不同公司交谈过。这是三家非常不同的企业,拥有不同的市场和不同的商业模式。当询问他们为什么要重建,他们共同的反应是改变的成本太高了。(有趣的是,其中的两个还提到目前EJB框架过于沉重,他们正在寻找一个较轻量级的框架。除了开源框架如Spring,他们都正在评估EJB 3。)自动化测试(单元测试、接受测试、适合/适合性测试,等等)有助于降低改变的成本,帮助系统达到一个可知的状态。如果没有合适的自动化测试框架,改变遗留系统的任务会变得日益昂贵。

scrum9ken

 

 

 

图1.  NFI在收益上持续下降。

 

一个选择题

 NFI的管理人员认识到他们需要提高系统的功能,以保持竞争力。他们有三个选择:

 1. 给核心系统增加功能。这将是高不可攀的昂贵,因为不断增加新功能将使软件成本呈指数型增长。这往往不是一个切实可行的解决方案。

 2. 引进一种临时解决方案,使得NFI在新功能之外,仍可以使用现有的遗留系统。这不能解决根本的问题,但能够给公司更多的时间。这种方式常用的一种做法是,在现有遗留的API上建立一个Web服务层。新功能的建立与现有系统并列,两者在Web服务层次上结合起来。但当有新数据需要被添加到遗留的数据模型时,会发生什么呢?

 3. 使用新的平台和技术重建现有的功能。这种方法可以解决根本的问题。然而,价格比选择2昂贵(但低于选择1)。NFI怎样决定哪种选择最适合于他们的情况呢?

 图表证据

 为了论证起见,我们假定NFI决定重写现有的功能。我们可以画一个图表,反映收入(不断下降的)和功能(不断增加的)随着时间的变化情况(见图2)。

scrumasdfte

 

 

图2. 当功能增加时收入在下降。

 我使用故事点作为衡量功能的方法,但假使测量单元是连续的,你可以使用任何东西。我还假设任何重写的系统更容易维护,因为改变的成本更低了。我认为这是合理的假设,如果某些极限编程(XP)的做法(如持续集成(CI)、测试驱动开发(TDD)、重构等)被使用的话。

 从图2的表中可以看出,重写功能的工作将在2004年中完成。这种情况下,NFI的选择是切实可行的。如果公司有时间,这是一种需要进行调查的方法。但是,当重写遗留系统最基本功能的时间预计比该公司维持正收入的时间更长该怎么办呢?(见图3)。

 scrumcneert

 

 

 

图3. 重写功能需要较长时间该怎么办?

 决定性因素

 在这种情况下非常明显,公司面临一些困难的决定。可能存在一些临时解决方案,允许NFI既使用现有系统,同时又建造一个新产品。NFI可能决定借钱为重写筹款,或NFI可能会考虑把任何剩余的资金分给他们的股东。不管最终如何决定,通过绘制一些简单的图表,介绍给管理人员许多不同的行动选择是可能的。

 关于作者:

Kane Mar

Certified: CSM, CSP, CSC, CST

Location: Australia

此文由scrum中文网整理,转载请注明