概念:旧系统演进
此概念定义了更新、合并或重新开发旧系统的路线图。
主要描述
生命周期范围内的活动:
  1. 介绍
  2. 确定基线
  3. 使用 RUP 进行演进
  4. 演进周期
  5. 摘要
  6. 参考
其他主题:

介绍

旧系统定义为“...很难进行修改和演进来满足新的和经常改变的业务需求”的系统。[1] 它通常意味着该系统庞大而陈旧。在此上下文中,它也表示“原先使用 RUP 以外的流程开发的系统”。

我们通过“演进”这个词来表示对旧系统进行更新、合并或重新开发的重大项目。因此,本路线图不介绍如何将 RUP 用于对成熟系统的持续维护。

通常情况下,首先需要做的就是通过回答如下问题为提议的演进定义远景:

  • 旧系统的价值在何处?
  • 您希望如何对其进行演进?
  • 有业务案例支持计划的演进吗?

对这些主题更详细的讨论可在指南:为旧系统演进定义远景中找到。

演进旧系统的常见困难包括:

  • 系统的可理解性差。
    • 文档陈旧。
    • 最初的开发者已不在,而其他人员对该系统的实际运作方式了解有限。
  • 系统是用旧的软件开发方法和技术开发的,这些方法和技术可能不适用于未来的开发工作。

与所有的项目一样,RUP 的基本原则同样适用于旧系统演进项目。

这些原则是:

  • 早期降低风险
  • 迭代开发
  • 根据具体、可测的证据进行进度评估
  • 由众多较小但赋有职权的团队组成机构
  • 不断验证质量
  • 范围管理
  • 按需生产工作产品

这已构成了基本的 RUP 生命周期模板,分为“先启”、“精化”、“构造”和“移交”四个阶段,完全适用于旧系统项目。这然后使 RUP 的大多数项目管理活动同样完全适用。

下面进一步详细讨论 Rational Unified Process(RUP)为处理旧系统的演进所作的调整。

确定基线

如果不只是应用 RUP 生命周期,而且还要使用 RUP 演进规程的其他规程,则您需要确定一个起点。您必须确定描述旧系统所必需的工作产品的最小集合。

您需要的工作产品数量因演进的范围而可能有所不同:

  • 需求
  • 体系结构和设计
  • 测试
  • 用户文档

一旦确定了该 RUP 工作产品基线,就可以继续旧系统项目,就好像它是一个 RUP 演进周期那样。

确定最小的一组工作产品,这使得每当 RUP 需要对旧系统进行反向设计时,您的项目能够继续。 反向设计是指尝试确定、抽取或重新创建足够的信息以便使您能够延续项目,就好像该项目原来就是使用 RUP 开发的那样。 正是由于这一点,许多项目经理准备对其旧项目放弃 RUP,因为他们发觉反向设计工作太浪费时间了。但其实并不需要如此大费周章,因为进行反向设计的目的不是为了重新创建每一个单独的工作产品,而是为了了解当前系统的主要属性,并确定哪些属性应当保留,哪些应当替换或升级。

您可以对这些工作产品使用 RUP 模板以及相关的一些指南和核对表,但是您可能首先需要对模板进行修改以避免记录不需要的元素。 在许多情况下,您可以通过交叉引用来“填写”模板,即指明哪些现有文档中可以找到对应的信息。 如果现有的文档是 HTML 格式的联机文档,则可以使用超链接。

请注意,确定基线的这个步骤并不是 RUP 独有的。无论您接下来使用什么流程或方法,都需要对现有的系统进行一些反向设计。 Web 站点“Renaissance”是一个 Esprit 的反向设计项目,它是一个有关反向设计信息的好来源。

需求

也许旧系统的最大价值在于它可以作为新系统的需求规范。

例如,当我们启动 Rational 时,远景文档的初稿中写到“...it has first to do everything that the Rational Environment (version Delta) does, and do it no slower.”。然后我们从 Rational Environment 指定了偏差:添加的功能和删除的功能。

聪明的团队绝不会回头记录旧系统的需求,所以您不必从头开始确定所有的需求,而只需要确定主要的用例。 您或许已经按当前用户手册中所述的那样确定了用例。 使用库中的用例(报告:用例模型调查)可能就够了。您只需要对需要更改的用例进行详细设置。您的营销或安装文档可能产生许多非功能需求:能力、大小和性能特性、操作系统、内存、外设、其他软件、常规局限性以及大多数“同族”。如果您尚未使用需求管理工具,则现在开始使用可能正是时候。 最后,在执行此反向设计时要创建的另一个好工件是旧系统中使用的术语词汇表 ,其中收集了遇到的术语。在演进时,它的价值是非常大的。

体系结构和设计

无需使用面向对象的(OO)技术完全重新设计旧系统。但是,您需要尽可能精简的体系结构信息。 您可以创建一个最精简的软件体系结构文档,从实施视图开始:什么是各种子系统或代码的主体?什么是至关重要的接口?如果旧系统是分布式的,则通过这些信息就可以确定部署视图流程视图。您需要对现有的软件进行精确地盘点,清除地确定每个元素以及它们之间的关系。 如果尚未对软件使用配置管理,则现在开始对其进行控制正是时候。

对接口以及接口的使用场合进行描述是至关重要的。随后,确定不受演进影响的子系统,即旧系统中稳定的、核心的、可以重复利用的部分。 您需要一份详细的软件设计文档以及这些接口的描述吗?如果您已经有了这样的文档并且觉得可信,那再好不过,但是在您了解哪些部分需要更改之前,请不要投入许多的精力来创建该文档。 请根据具体情况处理。工具可以帮助您在很短几天的工时内完成反向设计。

您还需要确定旧系统中需要迁移的各种数据源,并将它们的数据概要信息记录在数据迁移规范中。在您开始定义现有数据源和新版本的系统所需的数据之间的数据映射时,这将成为至关重要的信息。

测试

为旧系统开发的所有测试、测试脚本、测试用例以及测试装置大部分仍适用于新系统。

用户文档

除非有因素要求对旧系统进行彻底的修补,否则旧系统的用户文档可以构成新系统的良好基线。

使用 RUP 进行演进

一旦您确定了最底的 RUP 工作产品基线(其中多数引用自现有信息),您就可以继续了。 RUP 的大多数任务都适用,就如它们对于全新的开发项目在构造阶段迭代和移交阶段迭代中一样。 但是,始终请尽可能地仔细考虑要从 RUP 选择的任务;对于不必要的任务或工作产品,请不要执行或创建。

需求管理

使用用例来表示新需求。您可能必须为现有的功能重新创建用例以便更好地说明发生改变之处。 如果需要添加或更改多个用例,则您可能会发现从词汇表派生较小的域模型很有用。

体系结构和设计

您可能希望将面向对象的技术和 UML(统一建模语言)用于新的开发。一种方便的方法就是将受影响最小的子系统看作大的组合类(尤其是在绘制时序图时)。 得到的设计模型应当只加入体系架构中重要或需要演进的类的详细信息。可以通过将这些类的功能映射到现有的代码来为这些类创建代理。

如果您的长期目标很远大并且要针对旧系统进行完全的、逐步的替换,则您必须对新系统进行体系结构设计,然后将其与现有的子系统映射。 您可以创建包装器来将一部分现有的代码封装起来,使其看起来是用面向对象的技术设计的。 使用不同的包装器对整个系统进行重新汇编,这可以作为精化阶段中的内部里程碑。 当进入用例设计时,您的用例实现将显示对不同的现有子系统的影响。 则您就可以确定这些“封装的子系统”中哪些需要在 EAI(企业应用程序集成)框架中进行转换、移植、重新编写或集成。

数据迁移规范需要通过“源-目标”数据映射完成。它将用于实施执行数据迁移所必需的迁移组件。

在少数情况下,您可能可以使用诸如 IBM Rational XDE 或 Rose 等工具对元素进行反向设计,将现有的代码转换为 UML。 但是不要盲目地依赖这些结果;它们始终需要人工干预。

部署

新系统的部署可能比原始开发更有挑战性,这取决于演进的范围。 如果您将系统迁移到了新的体系结构或重新开发了其中的大部分,则您必须选择一个策略:是将某些部分一次性从旧系统转换到新系统,还是使用分阶段的策略并以较小的渐进式步骤进行转换。 您甚至可以对两个系统同时进行操作,直到新系统完全可以信赖为止。 实际上,对旧系统进行部署经常比部署新应用程序要棘手得多,因为您需要考虑数据转换和迁移、操作的连续性和人员的重新培训等问题。此部署策略可以在部署计划中描述。

其他规程

其他软件开发规程及其任务、指南、技术和工具同样适用,例如测试和实施。 当您在已有许多工作产品的情况下开始时(有时候它们之间存在着复杂的依赖关系),与在新开发中相比,配置管理的相关性可能更大并且需要在项目的更早时候进行。 在旧系统升级时,变更管理是一个占支配地位的活动。

通常,决定对旧系统进行重新开发也表示有机会通过业务建模重新设计业务流程,这可能引起新系统的其他需求。

演进周期

旧系统演进项目将经过与所有的 RUP 项目相同的各个阶段。这些阶段的目标实质上是相同的;但是以下部分描述了特定于旧系统演进项目的地方。

先启阶段

RUP 先启阶段指定了您将生成一个远景文档和业务案例,以及一个指定了需要重新创建哪些工作产品的初始开发案例。 在此阶段中,还将开始对某些工作产品进行反向设计过程:主要是需求和体系结构,以便能够选择合适的演进策略并估算成本。

精化阶段

在此阶段中,将完成 RUP 基线,它是演进所需的最小的一组工作产品,包括将某些旧的工作产品转换为新的工具集。 对于简单的扩展,这可在一个很短的迭代中完成。 但是如果有大量的体系结构更改需要完成(在迁移策略或重新开发中),则在此精化阶段中需要多个迭代才能实施新的体系结构基线。 该精化阶段甚至是占支配地位的阶段,而在构造和转换阶段几乎没什么要做。 测试将放在新环境中进行,而回归测试可以在初期开始。 与原始开发的精化不同,从开始时就有大量的工作产品(尤其是代码)需要管理,并且变更和配置管理规程中的任务可能必须在初期特别注重。

构造阶段

此阶段除了许多工作涉及对现有代码进行连接或重写而不是开发新代码,与任何其他 RUP 项目并没有明显的不同之处。 其他元素则根据需要进行反向设计、重新设计和记录。

移交阶段

移交阶段可能比较麻烦一些,这取决于从旧系统到新系统的部署策略;请参阅上面的部署部分。

RUP 的迭代方法在进行旧系统演进时特别有用,因为每个迭代都有其具体可测的目标。 负责 Rational Apex 项目的经理 Joe Marasco 写道:

“我们确定了功能中的哪些部分需要首先移动,哪些部分无需更改就可移动,而哪些部分在以后的迭代中移动。 Sun 操作系统上的版本推迟到以后的迭代中,一旦 AIX 上的版本稳定下来就可以进行。 不要期望一天之内就看到蝴蝶破茧而出,而应当对它的蜕变进行规划,并跟踪其一代一代的演变过程。 我无法想象还有其他什么方法能够对复杂的旧系统演进进行管理。”

摘要

如何将 RUP 应用于旧系统?

  • 首先,了解您想做什么。
  • 其次,理智地利用已有的资源。
  • 最后,将注意力放在 RUP 的原则而不是细节上。

RUP 中的大部分可用于旧系统的演进,但或多或少需要一定的定制和程序,这取决于您设想的演进类型和掌握了多少有关旧系统的信息。

正是由于它是一个旧系统,因此没有理由不建立远景文档(它描述了您要实现什么目标)、项目计划(列出主要的里程碑以及在该时间点上想要完成的目标)、迭代及其特定目标(可能)以及风险列表。您还需要一个业务案例以便能够讨论进行该项目的益处及将采用的方法。

其他 RUP 工作产品同样可以通过从现有的系统抽取或对其进行反向设计的方法来开发。 但是,应当明智地采用此方法,因为继续使用和引用现有的文档通常比将其更改为 RUP 格式更划算。

需要小心的是,我们曾遇到由于试图在同一时刻进行过多的更改而使项目失败的例子:在旧系统的大演进(例如迁移到新平台)的同时进行流程更改(例如转到 RUP)并对工具集进行更改(例如转到 Rational Suite)。建议在进行旧系统主演进之前,在更早的项目中引入新的流程和工具,这样开发者就能够熟悉 RUP 的体系、内容以及支持它的工具。 为了避免增加项目风险,请不要同时引入过多的未知因素和更改。

引用

  1. Michael Brodie and Michael Stonebraker, Migrating Legacy Systems, San Francisco: Morgan Kaufmann Publishing, 1995.