UML衰落历史 - Laurence Tratt

22-10-04 banq

在过去的一两年里,有一些文章缓慢而稳定地试图解释UML缺乏长期成功的原因(如果您只有一个时间,我建议您阅读 Hillel Wayne 的文章)。幸运的是,我在 2000 年代初期参与了 UML 标准化,所以我从“内部”看到了一些事情。

在这篇文章中,我将尝试解释一些我认为导致 UML 垮台的因素。在某种程度上,这是一份历史文件,至少在我看来是这样。

背景
人们长期以来一直创建图表来记录软件的重要方面。在 80 年代末和 90 年代初的过程中,三种图表风格或更宏大的“方法”开始流行:Booch、Jacobson 和 Rumbaugh 方法。在两次合并之后,这三种方法被结合起来创建了 UML(因此“U”代表 UML 中的“统一”),通过 OMG(对象管理组)作为标准发布,该组织以前以CORBA 标准 。
UML 的标准化恰逢其使用的迅速增加,并且可能是其必要的先决条件。从我在 1990 年代后期作为本科生的角度来看,Martin Fowler 的UML Distilled书也是 UML 的重要组成部分,能够吸引广大读者。尤其是类图变得非常普遍,到 2000 年,UML 类图语法的简化已经接近成为一种通用语言。下面是一个简单的例子:


这显示了两个类:一个Employee类;以及属于 的员工的子类(带有空心三角形的箭头)Managers。所有员工都有姓名和薪水。经理管理零个或多个(箭头末端附近的“*”)员工。

2000年代初的情况
2000 年的情况大致是,UML 比任何人预期的要成功得多。尽管 UML 主要用于设计草图(即人类之间的沟通机制),但一些重要的行业(例如航空业)开始将其视为他们创建软件的更正式方法(即人与人之间的沟通机制)的合理基础。和机器)

到目前为止,最大的参与者是 IBM(它很快收购了孵化 UML [2]的公司 Rational并创建了最流行的基于 UML 的工具)。现在很难想象,但在 2000 年,IBM 不仅财大气粗,而且仍然有能力将整个软件行业推向理想的方向。IBM 的参与被隐含地视为 UML 可以赚钱的标志。

问题在于 UML 版本 1 显然不适合 IBM 和其他人的雄心壮志。不仅标准本身有些模糊,而且它的定义也相当模糊。在许多方面,UML 的原罪在于类图——迄今为止 UML 中使用最广泛的部分——在很大程度上被设计为当时最常见的面向对象编程语言——C++ 的图解符号。

在 Java 在 90 年代后期取得成功之后,UML 得到了扩展,因此它也可以在某种程度上准确地表示 Java 的某些方面,但是所使用的机制被广泛认为是一种丑陋的 hack,并且显然无法扩展到支持任意数量的编程语言。

逐渐形成了一个共识:需要一个能够精确表示软件的全新 UML 版本;并且新版本的 UML 本身需要一个严格的定义,以便客户能够使用来自越来越多的 UML 工具供应商的各种工具。从这个共识中出现了成为 UML 2 的愿景。

严谨的基础
早期的 UML 1.x 标准是相当标准的散文文档,通常含糊不清,并且缺少很多需要的细节。

标准化社区普遍认为 UML 2 需要严格的基础。然而,没有人确切地知道“严谨”应该意味着什么,或者应该如何实现它。逐渐地,一小群学者确实知道严格的含义以及如何实现它,他们开始参与标准化。

他们的想法本质上是使用 UML 的一个子集来为“完整的”UML 提供指称语义。实际上,这意味着可以从一个小的核心“发展”UML 规范,使用 UML 类图来进行大部分语义定义,并将 UML 的约束语言 (OCL) 用于细粒度的语义规范。

但他们中很少有人具备理解细节所需的背景。
我很幸运能够与一些关键人物一起工作,我花了一年或更长时间的时间盲目地复制他们正在做的事情,然后才深入了解基本概念。大多数人没有这样的一个机会。

这意味着一个人会经常在一个 20 人的房间里争论定义,最多 1 或 2 人实际上能够将讨论的结果转化为严格的(或者更准确地说,半严格的)语义——而且可能只有同样的 1 或 2 个人能够完全理解结果。

当我离开 UML 标准化世界时,在我看来,社区正在逐渐将其期望降低到 UML 1.x 的模糊性和“真实”严格性之间的某个地方。查看当前的 UML 2.5.1 规范似乎表明这就是发生的事情

规范什么?
传统上,“标准化”的理想是查看已经起作用的内容并将其定义为标准。

到 2000 年,标准化社区已经决定 UML 应该是创建软件的新方法的基础。到 2000 年底,OMG 积极地将人们聚集在一个名为“模型驱动架构”(MDA)的新愿景背后。这个想法是从 UML 模型中自动生成大量代码。


MDA 的基本思想是人们创建软件首先会创建一个“PIM(平台独立模型)”:一种编程语言中立的 UML 类模型。
然后(理想情况下,通过按下按钮)他们将创建一个更详细的“PSM(平台特定模型)”:一个带有特定编程语言(例如 Java)注释的类模型。
一旦对 PSM 进行了适当的调整,它将被转换为用户可以编译和运行的“低级”编程语言代码。
例如,如果我使用文章前面的类图作为我的 PIM:


我想最终创建一个 Java 系统,我可能会将其转换为以下 PSM:


PSM 将更多细节具体化:我指定了字段的可见性(“-”表示“私有”);我已经开始使用特定的 Java 类型(int和Set)。然后,我可能会按照以下方式生成 Java 代码:

class Employee {
  private String name;
  private int salary;
  public String get_name() { return this.name; }
  public void set_name(String name) { this.name = name; }
  public int get_salary() { return this.salary; }
  public void set_salary(int salary) { this.salary = salary; }
}

class Manager extends Employee {
  private Set manages;
}


MDA的愿景
在我参与工作的时候,我上面引用的MDA文本中的大部分细微差别已经消失了。在很大程度上,人们认为只有组织中最有才华的人才会参与到PIM的创建中来;然后一群二等公民将不得不从事从PIM创建PSM的苦差事;没有人需要担心从PSM生成的代码。

这个设想的深层缺陷对大多数读者来说可能是显而易见的,但标准化社区有意无意地训练自己避免思考这些问题。最明显的缺陷是:"行为"(即一个程序应该做什么的细枝末节)在哪里被指定?
UML类图对于表达程序结构来说是很好的,但它们并没有告诉你一个函数实际上应该做什么。
get_salary应该做什么可能是相当明显的,但如果我在PIM中给Manager添加一个print_names的函数呢?它应该打印出雇员的名字吗?按照字母顺序?有时OCL对函数定义的约束会清楚地说明函数应该做什么,但我们大多数人发现很难为复杂的行为提供精确的约束。
UML确实有状态机,但它们只真正适合于表达某些类型的行为。
UML的序列图和协作图在表达行为方面的能力甚至更加有限。

偶尔,有人会提出指定行为的问题:一般来说,他们要么被忽略,要么被告知这个问题很微不足道,不值得担心。花在争论PIM和PSM的细节水平上的精力要多得多--我记得在没有窗户的酒店房间里,人们为某个细节是属于PIM还是PSM而争论了一整天。

也许只有一个软件试图使真正的MDA愿景成为现实:Compuware的OptimalJ(早已停产)。
它得到了一个大团队的支持,但它是一个让当时的普通计算机屈服于一个怪兽。
我不得不为OptimalJ写一份评估报告,并很快意识到它试图实现的愿景是多么的有缺陷。是的,我可以创建一个类图作为PIM;按下一个按钮,创建一个PSM;按下另一个按钮,生成Java代码。
但是,Java代码里有各种各样的漏洞,我必须填补这些漏洞:如果我以任何方式改变模型,我写的一半的代码将不再编译,更不用说正确运行。
换句话说,OptimalJ将最琐碎的事情自动化,而将所有艰苦的工作留给了终端用户。OptimalJ背后的团队很有天赋,工作也很努力,但他们最终展示的是,MDA不仅没有提高程序员的生产力,而且实际上还拖慢了开发速度

与此同时,许多OMG的成员,以及OMG本身[8]在其富有魅力的领导下,开始投入越来越多的精力向更广泛的软件社区推销MDA愿景。当我开始被普通程序员问到 "我听说这个MDA/UML将使我们的工作自动化 "时,我才意识到这有多大影响。
我的标准答案是:"它主要是针对那些想创建简单软件的非程序员",我想这让我的谈话对象感到放心。然而,他们问这个问题的事实表明,MDA的营销已经开始发挥作用。问题很快就变成了:社区能否使MDA的现实与愿景相匹配?

( banq:MDA+DDD :https://www.bilibili.com/video/BV1Yo4y1f7rz/

QVT的兴衰
MDA的一个基本理念是:PIM需要转化为PSM,PSM需要转化为代码。渐渐地,标准化团体发现这种转换比最初想象的要困难得多。到2002年,这被认为是一个重要的问题。因此,社区决定,需要的是一个新的模型转换标准。由于我现在已经忘记的原因(也许从来都不知道),这个标准最终被冠以 "QVT(查询-视图-转换)"这个笨重的名称。
QVT在(我想)2002年底或2003年初开始征集提案。几个月后,有8个提案被提出来了[9],其中有些是在深夜的活动中产生的。我所参与的提案的核心部分来自于一个下午的讨论,然后我们在几周内将其整理成一个类似于文件的东西。令人惊讶的是,我们这个半生不熟的提案很快就被认为是 "领先 "的提案之一,这说明了其他一些提案的情况。

在MDA以及QVT所需要的各种转换中存在着一种基本的紧张关系,我将其简化为以下几点:
"强制性"(想想普通的编程语言)转换明确地指定了将输入转化为输出所需的步骤序列(例如,"对于E中的每个元素,通过调用函数f创建一个元素E'")。
"声明式"(想想Prolog)转换指定了输入和输出之间的关系(例如 "对于E中的每个元素,有一个形式为X的输出元素E'"),留下一个 "引擎 "来解决如何使输入和输出在规范方面正确。
命令式转换很容易写,但很难以非破坏性的方式重新运行:如果你已经改变了输出,就很难再改变输入,并看到输入的变化合理地反映在输出中。声明性转换很难编写(尤其是当输入和输出之间的关系很复杂时),但它有希望持续地重新安排输入和输出的顺序,即使两者都被单独改变了。

一些QVT提案断言只需要完全的交互式转换;一些提案断言完全的声明式转换是可能的;还有一些提案(比如我参与的提案)试图假装它们可以跨越这两个维度。这样不同的方法怎么可能最终成为一个单一的标准?

当时,OMG的会议每年举行5次,都是面对面的(这种程度的旅行现在让我感到害怕!),所以我们有很多机会试图找到一个妥协。然而,妥协是相当难找的。在一个极端,有一个营地想在他们现有的命令式编程语言上加一个徽章,并称之为QVT。另一个极端是一个阵营,他们相信人们可以指定一阶逻辑约束,并总是有效地找到一个最佳解决方案(这将导致已知的数学定律被改写)。

我所参与的建议则不那么具体。部分受PIM/PSM思想的影响,我们的建议是允许对转换(我们称之为 "关系")和低级实现(我们称之为 "映射")进行高级抽象定义。关系打算用UML式的图解语法来表示,但我们明确表示,任何语言都可以用于映射(尽管我们提供了一个 "模型转换语言 "的例子,它在一定程度上受到函数式编程式模式匹配的影响)。

不知何故,人们逐渐看到,我们的方法的一个变种可以满足两个竞争阵营,他们可以简单地声称他们的语言只是低级的QVT语言!有人想出了将转换的实现称为 "黑盒子 "的想法,因为任何语言都可以在黑盒子里使用而不被其他人注意到。这似乎是最终标准中使用的术语。

起初,我对我们的建议可能最终成为 "赢家 "的想法感到高兴。然而,慢慢地,我开始怀疑这样一个标准到底能达到什么目的:如果一个标准的实现没有任何方式的兼容,那么这个标准是一个有意义的标准吗?我被迫得出结论,答案是 "不"。

然而,我们无法创建一个有意义的标准,这掩盖了一个更深层次的问题:我们都不知道如何创建MDA所需要的远程规模、复杂程度和灵活性的转换。在我看来,我们无法超越玩具般的例子来扩展这种转换,而且我们缺乏可信的想法来这样做。由于这种转换是MDA的一个关键部分,因此QVT的失败也保证了MDA的失败。

一旦我意识到这一点,我就慢慢地减少了我的参与,转而专注于我的博士论文(我最终的论文中大约有三分之一是关于UML之类的转换的,也许这并不奇怪;另外三分之二是关于编程语言的。

总结
事后看来,我认为UML在2000年不仅达到了它的实际,而且也达到了它的潜在高峰:作为一个软件草图的媒介,人们只需要它的基本内容。
然而,标准化社区为UML制定了一个雄心勃勃的愿景,远远超过了草图。这个愿景是否能够实现,可以看作是一个真正的辩论问题:对我来说,似乎无可争辩的是,这样一个愿景与任何标准化过程都极不相称。
QVT是一个最简洁的例子,它试图将充其量只是早期研究的东西标准化,并不可避免地导致失败。
然而,虽然QVT中固有的标准化过度在很大程度上停留在OMG的范围内,但MDA的失败却被广泛关注。
不仅MDA被认为是失败的,而且它还破坏了UML作为草图语言的成功,把它变成了笑话的对象,直到现在它还基本上是这样。

我当时无法猜到这一点,但我参与的这一切让我学到了一些宝贵的经验,其中有两点我认为是值得强调的:

首先,也是最重要的一点,团体的动态发展可以使合理的乐观变成盲目的乐观,表达怀疑成为一种禁忌。当这种情况发生时,团体很容易偏向极端的立场,从而保证团体的失败。UML标准化社区对UML 2的成功越来越投入:起初,怀疑的观点被认为是指一些微不足道的问题;最后,这样的观点根本就不再被表达。社区只谈论成功,即使有大量证据表明失败是最可能的结果。同样,QVT在错误的时间是一个错误的想法,但人们如此渴望成功,以至于他们选择忽视根本问题。

第二,当标准化从 "使已经存在的东西标准化 "转向 "使我们认为好的但还不存在的东西标准化 "时,就进入了危险的领域。我相当喜欢研究,但标准委员会是做研究的最糟糕的地方。最好的情况是,最终选择了一个不令人满意的最低标准,但最坏的情况是,这个过程崩溃了。在我看来,如果一个标准化过程意识到它已经超过了最先进的水平,那么就不应该感到羞耻,最好是在取得有意义的进展之后再重新审视这个问题。

我开玩笑地把这篇文章命名为 "UML:我在其衰落中的角色"。实际上,更准确的说法是,在我与它有任何关系之前,它的衰落就已经注定了,我可能对它的成功或失败没有任何可观察的影响。但我希望你能发现我对这个警世故事的看法和半记得的记忆是有趣的

 

1