按:上周偶尔谈起UML,想到自己UML、UP(统一过程)的知识有5-6年没更新了,干脆趁没忘光都吐出来。吐槽文,达意第一,术语使用不严谨。
——————————————————-
为了嘲笑UML,我们必须追溯UML的初衷,于是我们必须了解现实世界和软件世界之间天然的隔阂。虽然人们对软件已经习以为常,但是软件的构造并不像其他物理工具的制造那样透明。对软件一无所知的人来说,“编程”一词或多或少包含了“魔法”的成分。
如果对软件的内在机制有所了解,就可以更容易地表达软件与现实之间的鸿沟——即,描述现实世界的自然语言和描述软件世界的机器语言之间的失配(mismatch)。现实世界的需求不能轻易地被机器语言表达,这是鸿沟所在,或者更专业地说,是软件构造复杂度的来源。
一直以来,计算机行业用两种方法降低这种复杂度。第一种方法是对机器语言进行封装——通过引入高级语言、面向对象等概念,使编程语言可以更直接地描述现实世界。
(题外话,这是为什么从数(美)学上看编程语言越来越dirty。因为虽然Lisp很美——美到某本书某页最下方巴掌大的Lisp代码包含了计算的本质,但这种美却不能帮助Lisp更好地描述dirty的现实世界。)
但因为任何编程语言本质上都和图灵机等价,所以编程语言与现实世界的接近程度是有极限的。现存的编程语言依然难以直接描述复杂的现实。
于是计算机行业用第二个办法来弥合现实与软件的隔阂,这就是建模(modelling)——通过建模将现实世界抽象为模型,使现实世界更加清晰精确;编程语言不再直接描述现实世界,而是描述现实世界的模型。
“建模”包含两部分内容:首先是行为(“建”),即如何构造模型的方法;其次是结果(“模”),即作为方法制品的模型。
UML模型是一种用于构造软件的模型,是现实世界和软件世界的有效中介物。UML模型被用来描述现实世界的结构,并保证描述结果和软件结构天然近似。
但UML不是一种建模方法,UML没有定义将现实世界转化为UML模型的建模方法。实际上,使用UML模型的建模方法被称为“Unified Software Development Process(统一软件开发过程,缩写为UP)”。
UP的官方定义语是“用例驱动,以架构为中心,迭代增量的开发过程”。UP以模型为中介,降低软件开发的复杂度,帮助人们更容易地将现实世界的需求转化为软件。UML模型仅仅是UP的制品,而且仅仅是制品中的重要部分。一个未必恰当的比喻:UP是催动UML招式的内功心法。
遗憾的是现实中UP被丢弃、被遗忘、被不为人知。于是产生了各式各样对UML的误用:
– 比如,以为UML用例图就是用例;以为画小人圈圈就描述了需求。实际上,UP中首先要用文档附以领域模型和业务模型描述需求。每个用例都是从需求中抽取,并且是包含参与者、前置条件、后置保证、主要事件流、扩展事件流的完整文字描述。用例图仅仅用来追溯索引用例的图示。
– 比如,以为UML只包含类图;以为类图是银弹;以为使用UML就是画一张事无巨细的类图。其实UP中包含构造系统类图的完整流程方法,这包括:首先抽象现实世界的概念关系构造领域模型类图。而后以用例为中介精化领域类图,从用例中抽取包含新辨识概念关系的分析类图。而分析类图又会在后面的过程中被精化为设计类图,直到被用来指导具体实现。
– 比如,因为各种误用,以为软件开发的复杂性是UML造成的,以为摆脱UML就摆脱了软件开发的复杂性。实际上,软件开发天然复杂。摆脱UML不意味着人们可以用编程语言直接描述(具备一定复杂度的)最终系统。相反人们还是会以“土法炼钢”的方式构造自己的中介物。
此处我也无意为UP布道。不过我想说当我们像上面那样使用UML并造成混乱的时候,我们不应该嘲笑UML,UML应该嘲笑我们,因为我们才是混乱的根源。
当我们嘲笑UML的时候,我们到底应该嘲笑什么?
UML或曰UP的最大问题在于:它们认为模型是解决一切问题的银弹。
实际上以建模来弥平现实与软件的鸿沟,需要经历两个步骤:首先是对现实进行抽象,将现实转化为一种更精确更易理解的模型;第二步则是将模型“具象”到软件世界,即用编程语言实现获得的模型。其中的第一个步骤中,模型作为最终制品很重要;但第二个步骤必须落实到编程语言对软件实现上。
UP没有认清这一点,所以UP没有定义出模型使用的边界,没有给出在抽象过程结束后抛弃模型的时机,也因此没有将注意力集中到编程语言对软件的实现上。相反UP要求对模型不断精化,要求模型不断接近最终的软件。
这导致UML或者更广义建模研究的终极理想成为:通过精化的模型直接生成运行软件,或者更直白地说企图用模型替代编程语言。
然而无论直观感觉,还是多年的研究结果都表明:在企图精确描述软件世界时,模型并不比编程语言更优越——即,在深入到一定细节后,表达等量的内容,模型和编程语言同样复杂(如果前者不是更复杂的话)。
所以以模型替代编程语言的所有努力看上去是注定会失败的。UML是所有这些徒劳无功的形象代言人。
因此,我想,只有当我们看到那些事无巨细的类图、极端精确的时序图,看到那些双向转换模型的纷繁规则,看到那些神似编程语言的“建模语言”时,我们才可以去嘲笑UML。
因为这些多少代表了UML/UP以为自负可以达到,但其实不可能达到的境地。