1.4 UML简史
随着市场所要求软件的复杂度不断增大,软件开发的方法学一直在进化。从最开始没有方法,到简单的功能分解法,再到数据流/实体关系法。进入1990年代,面向对象分析设计(OOAD)方法学开始受到青睐,许多方法学家纷纷提出了自己的OOAD方法学,流行度比较高的方法学主要有Booch、Shlaer/Mellor、Wirfs-Brock责任驱动设计、Coad/Yourdon、Rumbaugh OMT和Jacobson OOSE。
这种百花齐放的局面带来了一个问题:各方法学有自己的一套概念、定义和标记符号。例如现在UML中的操作(Operation),在不同方法学中的叫法有:责任(Responsibility)、服务(Service)、方法(Method)、成员函数(Member Function)……同一个类图,用不同方法学符号各自表达如图1-4所示。这些细微的差异造成了混乱,使开发人员无从选择,也妨碍了面向对象分析设计方法学的推广。
图1-4不同方法学图形比较(同样一个三角形符号,在Coad/Yourdon方法学中用于表示关联,而在OMT方法学中用于表示泛化。)
1994年,Rational公司的JamesRumbaugh和Grady Booch开始合并OMT和Booch方法。随后,Ivar Jacobson带着他的OOSE方法学加入了Rational公司,一同参与这项工作。他们三个人被称为“三友”(three amigo)。这项工作造成了很大的冲击,因为在此之前,各种方法学的拥护者觉得没有必要放弃自己已经采用的表示法来接受统一的表示法。
1996年,“三友”开始与James Odell、Peter Coad、David Harel等来自其他公司的方法学家合作,吸纳他们的成果精华。1997年9月,所有建议被合并成一套建议书提交给OMG。1997年11月,OMG全体成员一致通过UML,并接纳为标准。
从2005年起,UML被ISO接纳为标准。相当于UML 1.4.2的ISO标准是ISO/IEC 19501,相当于UML 2.1.2的ISO标准是ISO/IEC19505。2012年,ISO继续接纳UML 2.4.1为ISO/IEC 19505-1:2012 和ISO/IEC 19505-2:2012,接纳OCL 2.3.1为ISO/IEC 19507:2012。
2011年,中华人民共和国也发布了统一建模语言国家标准GB/T28174。
UML的最新版本是OMG于2015年6月通过的UML 2.5。相关网址如下: OMG UML 2.5规范:http://www.omg.org/spec/UML/2.5/PDF ISO UML规范: http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=52854 中华人民共和国国家标准:http://www.chinagb.org/ChineseStandardShow-197675.html |
时间过去十多年了,UML不断发展,在表示法上已经获得了胜利。随便打开一本现在出版的软件开发书,里面如果提到建模,使用的符号基本都是UML,即便在纸上随便画个草图,样子也是UML的样子。各种主流的开发平台也相继添加了UML建模的功能。OMG还和各种行业标准组织如DMTF、HL7等结盟,用UML表达行业标准。
另外,以UML为契机,掀起了一股普及软件工程的热潮,在UML出现后的几年,不但有关建模的新书数量暴增,包括CMM/CMMI、敏捷过程等软件过程改进书籍数量也出现了大幅度增长。制定UML标准的角色(OMG)、根据标准制作建模工具的角色(UML工具厂商)、使用UML工具开发软件的角色(开发人员)这三种角色的剥离,也导致建模工具的数量和种类出现了爆炸性的增长。而之前的数据流等方法从来没有像面向对象分析设计方法一样,出现UML这样的统一表示法,从而带动大量书籍和工具的产生。
最开始一批UML书籍,基本上是方法学家所写。最近几年,以“UML”为题的新书大多为高校教材或普及性教材。这并不是说UML已经不重要,而是没有必要再去强调,焦点不再是“要不要UML”,而是要不要建模、如何建模。
根据UMLChina的统计,UML相关工具最多时达168种,经过市场的洗礼,现在还在更新的还有近百种。有钱买贵的,没钱就买便宜的或者用免费、开源的,可参见UMLChina整理的UML工具大全:http://www.umlchina.com/Tools/Newindex1.htm。
1.5 各建模工作流中的UML
UML 2.5包含的图形如图1-5所示,一共14种(泛化树上的叶结点)。
图1-5 UML图形(根据UML2.5规范绘制)
可能您看了会说,哇,这么多图,学起来用起来多复杂啊。其实,UML像一个工具箱,里面各种工具都有。您只需要从这个工具箱中选择适合您的项目类型的工具用上就可以,并不需要“完整地”使用UML。这和编程语言类似。很多人说“我用Java”,其实只是用Java的一小部分,而且很长时间内只用这一小部分就够了。
经常有学员问:潘老师,能不能给一个案例,完完整整地实施了整套UML?这是一种误解,这样的案例不应该有。有一些建模工具自带的案例模型会造成误解,一个模型里把所有的UML图都给用上了,但这是工具厂商出于展示其工具建模能力的目的而提供的,不可当真。
各建模工作流可以选用的建模元素以及推荐用法如图1-6所示。
工作流 | 思考焦点 | 可选建模元素 | 推荐建模元素 |
业务建模 | 组织内系统之间 | 用例图、类图、序列图、活动图 | 用例图、类图、序列图 |
需求 | 系统边界 | 用例图、序列图、状态机图、活动图、文本 | 用例图、文本 |
分析 | 系统内核心域 | 类图、序列图、状态机图、活动图、通信图、包图 | 类图、序列图、(状态机图) |
设计 | 系统内各域之间 | 类图、序列图、状态机图、活动图、通信图、组件图、部署图、时间图、组合结构图、包图 | 用文本表达模型(所谓代码) |
图1-6 可选和推荐的建模元素用法
从“推荐UML元素”一栏中可以看到,常用的UML图形用例图、类图、序列图三种就够了。针对特定类型的项目,可以按需要添加图形,例如,开发复杂组织的运营系统,如果在业务建模时不喜欢用序列图,可以用活动图取代;对于系统中的核心类,可以着重画出状态机图来建模类内部的逻辑,针对质量要求很高的系统,每一个类可能都需要画状态机图,甚至还要画时间图。
另外,设计工作流推荐的做法是不需要画UML图,用文本来表达实现模型,即所谓“代码就是设计”——编码就是一种建模工作。计算机运行的是二进制指令,源代码实际上也是“模型”。之所以被称为“源代码”,是因为它是人脑需要编辑的最低形式模型。这个最低形式模型随着时代的发展不断变化,从最初的机器语言到汇编语言、过程式高级语言到现在流行的面向对象语言。见图1-7:
图1-7 “源代码”的发展历程
同理,如果人脑只需要编辑UML模型就可以实现系统,那么“模型就是源代码”。例如用带有设计级调试和强大代码生成能力的工具Rational Rhapsody开发实时嵌入系统,人脑只需要编辑和调试UML模型(类图和状态机图)。
1.6 基本共识上的沟通
不少开发人员并不喜欢用UML,更喜欢在白板上画个自造的草图,似流程图非流程图,似类图非类图,然后说“来,我给大家讲讲!”。这样的做法有巨大的“优点”:怎么画都是对的,关于这个草图的解释权归“我”所有。同事不好批评“我”,项目要依赖于“我”头脑中的隐式知识——要是“我”不“给大家讲讲”,大家就玩不转了。这样,“我”在团队里的地位就提高了。上面这种现象,在有一定资历、但又不对项目的成败承担首要责任的“高手”身上表现更明显。
★开发人员让我看他的模型时,如果开口说“我先来给你讲讲”,我都会拦住“如果还需要你先讲讲,说明你所想的没有体现在模型中。”
这种做法的本质是想通过形式上的丑陋来遮掩内容上的丑陋。动乱年代,数学家在牛棚中用马粪纸做数学推导,不代表就可以因为演算工具简陋而允许自己胡乱使用符号和概念;过去的作家没有电脑,不意味着作家可以随意写错别字和犯语法错误。开发人员故意选择简陋的形式为简陋的内容开脱,就如同作家故意选择不好的纸来掩盖自己文字功力不足的事实,并不是好现象。UML没有强调一定要用多么昂贵的工具来建模,但即使您在海边用手指在沙滩上建模,模型依然要概念清晰。
如图1-8所示,就像数学符号背后隐含着数学的基本共识,五线谱背后隐含着基本乐理一样,UML背后隐含的是对于软件建模的一些基本共识。这些符号幼儿园的小朋友都会画,但背后的共识需要一定的训练和学习才能掌握。掌握之后,团队在基本共识上沟通,效率会高得多,无效的低水平争论会少得多,有意无意遮掩的脓包也会强制露出。开发人员如果习惯于画“草图”,用“模块”、“特性”等词汇含糊不清地表达思想,在严谨建模思维的追问之下,往往会千疮百孔,暴露许多之前没有想到的问题。这是一些“高手”潜意识里不愿意直面UML的深层原因。
图1-8 符号背后的基本共识
面对一个棋局,下一步怎么走?在业余棋手看来到处都是正确答案,在职业棋手眼里,值得讨论的选项只有两三种,因为职业棋手针对一些基本的技能形成了共识,大大减少了思考中的浪费。
有些“敏捷”软件组织,抛弃了所有“文档”(前文已说过,如果使用“文档”这个词,说明概念不清楚),更喜欢口头交流,动不动就开会,你一嘴我一嘴,场面看起来热热闹闹,其实沟通的效果不好,更谈不上思考的深度和知识的沉淀。对比一下菜市场民工下象棋的热闹和职业棋手比赛时的沉静就知道了。“敏捷”的理由也不成立,菜市场的民工判断局势的速度快还是职业棋手判断局势的速度快?江湖棋手不看棋书不打谱,摆个路边摊够用了,如果参加职业比赛,非被打得落花流水不可。
★有的开发人员的“十年工作经验”实际上是“一年工作经验用了十年”,一直在热热闹闹的民工层次徘徊,没有积累和成长。
但是,这里要注意一点:使用UML沟通仅限于软件组织内部,UML模型不是用来和涉众沟通的!和涉众沟通的技能在第7章详细叙述。
1.7 建模和敏捷(Agile)
敏捷运动在1990年代中期兴起,当时敏捷过程被称为轻量(lightweight)过程。2001年,Kent Beck、Martin Fowler等人聚集在犹他州的Snowbird,决定把“敏捷”作为新的过程家族的名称,并提出以下宣言:
个体和交互 胜过 过程和工具
可以工作的软件 胜过 面面俱到的文档
客户合作 胜过 合同谈判
响应变化 胜过 遵循计划
敏捷运动可以看作是“政治正确”的左翼思想在软件开发领域的一次演练。这次演练和在人类社会其他领域已发生的左翼演练一样,迅速取得了成功,带来了一批“有信仰”的软件从业者。我有专文《敏捷传播的最佳实践》[潘 2012]对比了敏捷和社会主义理论背景以及成功经验的共通之处,此处不再细谈,只谈谈口号和方法的区别。
有口号有方法,有口号无方法,无口号无方法,这三种情况哪一种最坏?可能有的人认为无口号无方法最坏,其实不然,无口号无方法地呆在原地,可能会慢慢衰落,但不是最坏的。历史上各种最坏的大悲剧往往和“有口号无方法”有关。
最坏的事是“有口号无方法”的“好人”做的。偷盗抢劫的坏人知道自己做的是坏事,会暗自收敛,而“好人”认为自己是做好事,所以会做得很极端,如果有口号无方法,大悲剧就发生了。例如,有人谈论社会上存在的(□□此处作者删去三十二字□□)问题,列举的大都是事实,结果给出的解决方案却是(□□此处作者删去二十八字□□)。
软件开发领域也是如此。经常有开发人员吐槽软件项目中的各种痛苦,大都是事实,结果给出的解决方案却是"裸奔"。开发团队要警惕有口号无方法的开发人员,他们擅长喊口号打鸡血,上班时间端着茶杯大谈老子、庄子、孙子、禅、道……。
口号:我们只做最重要的需求,尽快把系统推向市场。问题来了:怎么知道哪个需求最重要?拍脑袋?建模提供了愿景、业务建模等方法,帮助迅速定位最重要的需求。
口号:设计要分离变和不变,这样可以减少变更的成本。问题来了:怎么知道哪些变哪些不变?抓阄?建模提供了领域分析方法,帮助厘清各种概念的变和不变。
有两幢大楼,地震中一幢倒塌了,另一幢没倒塌。是否倒塌的直接因素可能有大楼的结构、所用的材料、所在位置的地质环境等,但这些都涉及到比较艰深的工程力学、材料学和地质学知识,可能就会有人懒得去想,干脆就直接嚷“有人吃回扣了!”,就算经过调查没人吃回扣,他也会从工作服的颜色、工人是否结对洗澡,施工队开会时是否站立等方面来找原因,因为这相对容易。
本书内容针对的是影响软件质量的直接原因——缺少各种建模技能。许多团队实施过程改进容易流于形式,根源往往就在于建模技能的不足。如果把改进的焦点先放在建模技能上,开发人员技能提升了,适用什么样的过程自然就浮出水面,没有必要去生搬硬套某过程。或者说,技能增强了,更能适应不同的过程。UML建模没有绑定到特定过程,不过当前主流的软件过程都是强调增量和迭代开发,所以应该把前面所讲的业务建模、需求、分析、设计看作是一个迭代周期里的工作流,做一点业务建模,做一点需求,做一点分析,做一点设计……不可误解成“做完了所有的业务建模才能做需求”……。
很多时候方法和过程经常被混淆,有人会把“敏捷”说成“敏捷方法”,其实“敏捷”是一个过程家族。之所以造成这个误解,也许和Martin Fowler把他介绍敏捷过程家族的文章起名为“新方法学(The NewMethodology)”有关。另一个常见的误解来自Robert C. Martin的书《敏捷软件开发-原则、方法与实践》,书中主要讲的是面向对象设计的一些方法(原理、原则和模式),这些方法并非Robert C. Martin首先提出,而且和敏捷过程没有必然关系,但是,经常会有开发人员误解面向对象设计的这些思想是敏捷人士提出来的。更有一些敏捷人士在没有学习和掌握软件工程知识的情况下,先高喊“砸烂一切”吸引热血青年,然后发现砸烂一切是不行的,又偷偷拾起过去被自己砸烂的东西,加上自己的“敏捷”包装,有意无意地给不了解历史的新入行开发人员造成“这是敏捷发明的,那是敏捷发明的,所以把敏捷挂在嘴边的人最懂”的印象。
我刚开始为软件组织提供服务时,有一次和一个软件组织的经理交流,经理说“我们用的是面向过程方法”。我一开始信以为真,认为如果能做到用面向过程方法,从组织级、系统级到模块级层层分解也不错的。后来发现,经理所说的“面向过程方法”其实是随意的功能分解,也就是没有方法。
类似的场景还有:软件组织负责人说“我们现在采用的是敏捷过程”,稍为深入了解,多半会发现其实他所说的“敏捷过程”就是没有过程。不要让“面向过程”、“敏捷”成为偷懒的庇护所。
还有一个常听到的偷懒庇护所是“软件开发是艺术”。软件开发是不是艺术,我不知道,不过就算软件开发到了极高境界真的是艺术,恐怕也不是大多数人目前有资格谈的。下棋到很高境界,也有各种流派风格,但那是在通晓了基本棋理的基础上演变出来的,连基本棋理都没有掌握的初学者,把自己的胡思乱下也当成“流派”就不合适了。
师父纠正少林弟子武功招数的细节,弟子懒得去了解为什么按师父教的会好一点,反而说“不要纠结于细节,天下的武功又不仅仅只有少林这一派”,以为这样一说,自己就可以摇身一变成为武当派高手了。其实,少林派武功学精了,如果对武当派武艺感兴趣,转起来容易很多。如果某人学少林派武功时面对细节总是以“不纠结”为由拒绝进一步思考,很难相信他学习武当派武功时会好到哪里去。
本书到现在为止,已经说了很多回“偷懒”,就是强调世上无易事,好的方法应该能强迫您思考,强迫您付出心血和汗水来获得竞争优势,反之就是忽悠,就像前些年一些甜得发腻的敏捷宣传。