使用 UML 建模的理由
由 Kris Richards 和 Cindy Castillo 创建,由 Bob May 维护
最近更新:2007 年 10 月
摘要
统一建模语言(Unified Modeling Language,此后称作 UML)的作用是提供一种语言和平台无关的建模注释。UML 工具的通用程度与 UML 的基础程度都比较高。本文主要介绍 UML 的基本概念,并让大家对建模的作用有一定的理解。本文并不是入门手册,有关基础内容可以参考文章提供的教程链接。这些教程演示了如何使用 NetBeans IDE 中提供的 UML 功能。
有的程序员在开始编码之前永远都抽不出时间对项目进行建模,还有一些程序员在对系统进行编码之前从不考虑为系统创建模型,希望这篇文章能够让他们了解建模的重要性。本文给出了一些方法和策略,可以提高程序员的开发效率,并且能够节省大量时间。本文中的信息可能会对如下理论作出挑战: "我们从没有时间把事情做对,但始终有时间再次去做它。
目录
简介
当咖啡店中,您忽然想到了"一个惊人"的软件构想,便激动地抓过一张餐巾纸,然后将软件结构绘制成各种图片。您的图画就像是鸡爪划出的一样,除了您自己谁也看不懂。
但它对您却意义非凡:这些鸡爪划痕是对一个想法的阐述,在接下来的两年人生中,您可能会致力于让这个想法逐渐变为现实。您所创建的正是一个初步的模型。在您的心中,方框代表一个元素,而圆、三角形和直线代表着另一个元素。您在餐巾纸的背后发明了一种建模语言。只要您可以编译和运行这张餐巾纸,您就可以 大功告成。这并非像它听起来的那样不可能。如果您花接下来的几个月时间教会计算机每个餐巾纸对象代表什么,以及如何为每个对象生成源代码,编译餐巾纸 将成为可能。
在餐巾纸建模整个过去的 25 年时间里,人们陆续创建出了很多十分优秀的建模语言。进入统一建模语言(UML)时代之后,建模人员 收集到了他们所有的餐巾纸,并就每个对象的定义和对象之间的关系达成一致。借助这种统一建模语言,特定于语言的程序员开始 开发模板,以便为不同的对象创建代码。现在,只要您在作为 UML 一部分的餐巾纸上绘制对象,您的餐巾纸就会被编译。
"为什么需要建模?" 这是一个重大的问题!本文提出了两个答案供您考虑:将它们认作是 UML 用例。第一个答案在 编译餐巾纸 的内容下,其重点在于工程师在白板上或咖啡店餐巾纸 上构建想法草图。这一节内容的目标是显示建模在工程规划阶段中的优点。这一节里面包含多个指向参考指南的链接,它们可以带领 您找到执行建模的细节。
针对“为何建模“问题的第二个答案在 他们在思考什么 一节的内容中,其重点在于让刚收到 300,000 行代码并被赋予维护和修复 bug 任务,因此在持续工作的沮丧工程师。他很高兴前任程序员知道条程序包,但仍然不明白它们是如何组合在一起的。如果这位工程师是您,而您习惯于通过视觉获取信息,那么您会希望看到一张系统图,从而了解原来的 程序员的思路如何。这是 UML 工具的一个常见用例。您可以有效地解析代码来创建一个模型(称为“反向工厂“),然后从这个模型可以创建出图。
下表列出了各种类型的 UML 图,这些图在网上随处可见,在这里列出只是为了方便起见。点击缩略图可观看特定图的一个例子。
| 用例图 |
 |
主要由角色 和用例 组成。用例图可帮助捕捉系统的功能需求。这始终是启动项目时要用到的重要图。 |
查看指南 |
| 组件图 |
 |
主要由主要系统组件 及其关系 组成。这种图是复杂系统的高级概览图。无论是在您的脑海里,在餐巾纸上,还是使用 UML 工具,您肯定为曾经参与过 的所有工程都创建过这种图。 |
指南即将面世 |
| 类图 |
 |
主要由类、接口 及其关系 组成。类和接口相当直观,但是关系的多样性、广义性和关联性可能会造成它有一点 复杂。当您了解系统中有哪些组件之后,自然会用图表示构成组件的类。 |
查看指南 |
| 行为图 |
 |
主要由行为 和判定 组成。这些图其实就是您用于获得代码综合流程的流程图和数据流图。 |
查看指南 |
| 协作图 |
 |
主要由对象 和消息 组成。这种图的重点在于对象之间的通信,这点类似于顺序图。 |
查看指南 |
| 开发图 |
 |
主要由部署元素(比如服务器)及其关系 组成。这是系统的逻辑拓扑。 |
指南即将面世 |
| 顺序图 |
 |
主要由对象(带有生命线)和调用消息 组成。顺序图用于描述系统中调用和不同对象创建的顺序。 |
查看指南 |
| 状态图 |
 |
主要由状态、转换、事件 和动作 组成。除非逻辑特别复杂,状态图很少是必要的。 |
指南即将面世 |
回到顶部
编译餐巾纸

您从咖啡店回来,带着绘有您想法的餐巾纸。您需要描述一个解决方案给您的团队或老板。所以,您把想法从餐巾纸抄写到了白板上,并将 所有同事都拉到会议室,并将这些想法展现给他们看。不会有软件工具能够代替白板周围发生的对话,但是如果必须把想法带出办公室,一般不赞成 发送 Polaroids 邮件或者发送带有白板数字照片的电子邮件。白板不会使对想法进行归档变得更容易,所以您可以稍后再引用它们。您可能不喜欢它,但您不得不找到一种 UML 工具,并创建出可以描述您的想法的模型。
虽然模型就是模型元素及其关系的一个集合,可以对这些元素进行分组,以组成图。这些图比元素的总和更好,因为它们提供了您的模型 的各种视图。不同的视图可以用于讲述应用程序的构建方式。用于可视化模型的图的类型取决于您的问题是什么。
开始,您可能绘选择创建一个用例图。这是一种优秀的概览图,可以确定工程的主要组件。尽管可以根据需要,用例图可能会很复杂,但它实际上只有两个主要组成部分:角色和用例。一个角色代表一个将与系统交互的实体。实体的例子可能会是与程序交互的“客户“ 或“银行出纳员“。角色甚至可以是一个第三方库或一部分硬件。用例图的主要意义是显示这些角色可以与您的程序交互。例如,一名银行出纳员可能“存钱“或“取钱“。在这个例子中,“存钱“和“取钱“就是 用例。没有代码直接与角色或用例相关,但是这些交互反映出了对工程中某些组件的需要。
在规划期间,通过用例进行的思考经常会被忽略,而且正如任何程序员都知道的那样,用例分析最终还是不得不发生的。思考工程需求是什么可以免于实现不必要的功能和忘记其他功能。创建用例图可以很好地公开任意俯瞰点。图无法让您不添加 不必要的功能,但是它至少会告诉您它们是不需要的。所以,第一步是执行一次用例分析并创建用例图。这篇 指南 可以指导您完成创建一幅用例图的过程。
用例分析和图的完成将自然地导致系统组件的粗略浮现。无论是在脑海中,在餐巾纸上还是使用 UML 工具,在成功系统的开发过程中,这一步永远不能被忽略。正式创建组件图的优点是,它可以帮助您定义构成组件的类和接口。如果读完了用例图指南,您可以看到分析 是多么重要。从指南结尾处的用例图,一些必要的组件都变得很明显;一个 Customer 组件,一个 Account 组件和一个 Database 组件。组件之间的交互可以借助协作图和顺序图进一步定义。这些组件代表着系统的可交付部分。这些是您的老板,您的客户,或双方同时必须 签名认可的部分。直到就组件达成一致之前,架构师和程序员都正在瞄准一个移动靶。但是当组件确定之后,细粒度的结构化工作就可以开始了。
这种细粒度的设计是从创建类图开始的。再次,这本现成的 指南 将带领您了解创建一幅类图地细节。如果试过开始创建精确的用例和组件图的艰辛,您可能会受到坐下来开始编码的诱惑。但是,记住上次您这样做之后,不久便不得不重新创建接口和超类,因为您开始编码时没有看到必要的关系。
创建类图时,您必须将所有部分都拼起来,从而反映出哪里需要接口、超类和甚至是整个设计模式。如此,您看到了这些图的优点是,它们在您编写几个类之前公开继承结构,以免让您重复地编写相同的方法。
使用 NetBeans UML 工具可以添加另一个重要的维度到类图中,即设计模式。如果您知道系统的某个组件将会利用一个或一组设计模式,只要将这些模式拖放到画布上,即可为您创建基本的组件。最好是,工具能够正确创建它。忘了试着记住设计模式的实际结构。NetBeans UML 功能提供了现成的 Gang of Four (GoF) 和 Enterprise Java Beans (EJB) 设计模式。如果经常使用自定义的设计模式,您可以将它保存下来,便于以后使用。
最好的消息是,这些工作都不会白费。如果您正在使用 NetBeans UML 功能,只要单击一个按钮便可把一个类图转换为 Java 源代码。您甚至可以设置有关如何生成代码的选项:标题,注释,变量安置,以及其他格式。这些设置甚至可以包括添加版权信息给所有生成的 文件。在开发周期中,光是代码生成就应该使这个步骤值得去做了。因此,值得花费时间首先创建模型,然后让工具生成所有的基本代码。
每个人都可以通过各种形式进行绘图。其区别在于,当图完成之后,使用 UML 工具绘制的图可以显示出一些工作规划方面的内容。餐巾纸往往用于清洁嘴边溢出的饮料,然后就扔掉了。每个经过深思熟虑的工程都会有一些形式的用例图、组件图和类图,当咖啡馆里的“假想工程“结束之后,这些图还能够存在相当长一段时间。
回到顶部
他们在思考什么?
UML 只不过是一种独立于任何编码语言的建模语言。因此,就像 UML 可以被转化为编码语言一样,编码语言也可以转化为 UML。这个 过程称为“反向工程“。这个过程有多种用途,但其中最常用的一种只是获得代码组织结构的视图:对象是什么,以及它们之间的关系如何?看代码的图可以暴露出设计模式和阅读代码时可能不明显的其他复杂之处。如果需要有关如何使用 NetBeans UML 工具的指南,可以参考 Reverse Engineering Java Applications。
尽管本文不是一篇指南,如果您正在使用 NetBeans 进行反向工程,有很多步骤都没有任何价值。您从一个免费形式的 Java 代码基础开始。对这个代码基础进行反向工程的第一步就是创建一个 NetBeans “Java Project with Existing Sources” 项目。NetBeans 中的向导可以帮助您完成这个过程。创建完工程之后,工程的菜单中将会添加反向工程一项。即便是对大型工程,这个过程也只会花上一小会时间。完成时,工程树中会出现一个 UML 工程。
现在可对这个工程进行随意操作。可以从生成的模型元素创建图。如果需要修改图,只要修改完重新生成代码即可(称为“正向工程”)。您可以要么替换掉生成模型的代码,要么把它保存在别处。注意这些功能中蕴含的能量。您可以从模型本身开发代码。这种灵活性 让您可以获得模型的所有可视化和报告能力,同时还能够编译和运行您的代码。它真的是两个领域的最佳交汇。如果您喜欢键入代码,而不是从图生成,您就可以这样做。当您的经理问您要一份代码检查,只要把代码反向工程以升级模型,然后把图带入会场即可。
尽管反向工程是一个相当有用的工具,可以帮助您理解遗留代码,它还是无法回答所有的问题。例如,用例无法从由反向工程创建而来的模型绘制而成。您可能不会期望这种输出,因为代码包含了用例所需的不同级别的信息。从反向工程创建时没有意义的图有组件图、行为图、协作图、 状态图和部署图。但是,因为类元素和关系是全部已知的,这些图中的任意一个都可以快速被创建,接着您就可以推理对随之自然发生的 问题的答案:什么是用例?什么是部署结构?什么是主要组件?您只需要提供与该图有关的丢失信息,便可拥有一个开发完全的模型。
回到顶部
结束语
UML 是一种语言。即使 UML 中存在优秀的可用工具,它也仍然是一种语言。如果没有理解这种语言的结构,工具中的设计模式只会让人感到沮丧。为了实现语言的“统一性”,UML 包含了大量功能。众多功能让 UML 工具变得麻烦和难于使用。Sun Microsystems 提供了一个类,用于在 面向对象的分析与设计 的上下文中学习 UML。借助您对 UML 中不同元素的上下文的了解,您的模型可以具有高水平的实用性和有效性。如果您使用了错误的元素创建模型,您的模型就无法转换为代码。
无论是架构师还是程序员,在任何比 HelloWorld 更复杂的工程中,建模都是必不可少的步骤。一些建模语言,例如针对数据库设计进行了调整,但是您只有时间学习一种建模语言的话,UML 已经成为了行业的建模标准。UML 工具,比如 NetBeans UML 功能,已经演变得如此成熟,以致于建模不再是时间的浪费,或仅仅是编程开始之后可有可无的学术练习。工具能够并确实可以帮助您完成编程工作,让您有机会再次在咖啡店开始一轮循环。
top