1.书籍信息

封面 image.png
书名 UML精粹:标准对象建模语言简明指南(第3版)
作者 Martin Fowler
状态 已读完
简介 在紧迫的时间压力下,程序员很难通过紧跟技术创新的脚步来享受软件工程领域的最新成果。正因如此,殿堂级大师Martin Fowler这本旨在帮助专业人士提升效率的图书一问世,立即给软件工程社区带来巨大震撼。其前两版经年畅销,因行文精炼自然、见解透彻而广受称赞。被誉为以软件设计为生者必备资料的第3版,更是带来有效面向对象设计的最佳思想及愈发便利的教学体例,引进交互概述图、时间图、组合结构等新图型,对类图、顺序图、状态图、活动图等也有较多更新。
资源
评价(满6颗) 讲了 uml 的 20% 内容,够用
⭐⭐⭐⭐

2.书摘

UML 时序图操作符
weread_image_134009536734758.jpeg
UML精粹:标准对象建模语言简明指南(第3版)
Martin Fowler
70个想法

◆ 第3版前言

它的智慧是永恒的:把每一件事情减少到实质,这样就可以使其功能更好地发挥出来。

◆ 为什么要花时间学UML

图形设计表示法已经出现一段时间了。对于我来说,它们的首要价值是沟通和理解。好的图形经常可以帮助沟通设计思想,特别是当你要回避许多细节时。图形也可以帮助你理解软件系统或业务流程。

◆ 第1章 简介

图形建模语言在软件业已经出现很长时间了。背后的基本驱动力就是:编程语言的抽象级别不够高,不方便讨论设计。

◆ 1.2 使用UML的方式

Steve Mellor和我分别针对人们使用UML的特征归纳出三种模式:草稿、蓝图和编程语言

使用草稿的目的是来帮助沟通想法或者展示所要做事情的可选方案

在逆向工程中,可以使用草稿来解释系统的某些部分如何工作

一种常见的做法是,设计人员开发蓝图级模型只做到子系统的接口,而让开发人员负责实现细节。

像这样可以做正向和逆向工程的工具被称为双程(round-trip)工具。

UML 2提供三种行为建模方法:交互图、状态图和活动图。

基于这个软件视角(software perspective),UML元素会相当直接地映射到软件系统中的元素。

从概念视角(conceptual perspective)看,UML表达对所研究领域概念的描述。

UML的创造者们认为图是次要的,UML的本质是元模型,图只是元模型的表示

◆ 1.4 表示法和元模型

大多数图形建模语言没有那么严格;它们的表示法看起来是凭直觉的,而不是正式定义的。

◆ 1.6 什么是合法的UML

。强制性规则(prescriptive rules)语言由官方控制,官方会说明语言中什么是合法的、什么是不合法的,以及你用这门语言所发表言论的含义是什么。

描述性规则(descriptive rules)语言要通过看人们在实践中如何使用该语言来理解它的规则

如果你要理解UML图,重要的是要认识到理解UML标准不是一切。在整个行业和特定项目中,人们确实接受习惯性用法。因此,虽然UML标准是UML的首要信息源,但不是唯一的。

如果你是一名草稿使用者或者蓝图使用者,重要的是不要太强调合法的UML。给系统一个好的设计更重要,我宁可有一个好的设计,但用的是非法的UML,而不愿意要合法却苍白的设计。

◆ 1.8 仅有UML是不够的

如果某项技术看起来适合你的项目,尽管尝试,不要犹豫。如果管用就用,如果不管用,就丢掉。(当然,对于UML图也是同样的建议。)

◆ 2.1 迭代和瀑布过程

迭代开发有许多名字:能想到的有增量、螺旋、演进和极可意(Jacuzzi)

瀑布的缺点,这条说的想给点个赞
>在过去几年,大多数软件过程作者,特别是面向对象社区成员,不喜欢瀑布方法。这有许多原因,最基本的原因是,瀑布过程中辨别项目是否真的还在轨道上非常困难。它太容易在早期阶段宣称胜利,却隐藏了进度延误的情形。通常,你可以真正辨别项目是否还在轨道上的唯一方法是生产已测试、集成的软件。迭代风格不断重复这样做,如果某些东西出了偏差,你会更好地得到警示。
仅仅为了这个原因,我强烈推荐项目不要使用纯瀑布方法。如果不能采用更纯粹的迭代技术,你至少也应该使用阶段交付。

在过去几年,大多数软件过程作者,特别是面向对象社区成员,不喜欢瀑布方法。这有许多原因,最基本的原因是,瀑布过程中辨别项目是否真的还在轨道上非常困难。它太容易在早期阶段宣称胜利,却隐藏了进度延误的情形。通常,你可以真正辨别项目是否还在轨道上的唯一方法是生产已测试、集成的软件。迭代风格不断重复这样做,如果某些东西出了偏差,你会更好地得到警示。
仅仅为了这个原因,我强烈推荐项目不要使用纯瀑布方法。如果不能采用更纯粹的迭代技术,你至少也应该使用阶段交付。

在许多领域中,例如制造业,返工被看做浪费。但软件业不像制造业;因此,通常重写已有代码比围着设计不良的代码打补丁要高效。许多技能实践可以大大地帮助你,使返工更加高效。

◆ 2.2 预测性和自适应计划

瀑布还在继续使用的原因之一是:人们希望软件开发可预测

软件项目复杂性的独特来源之一是理解软件系统需求的困难。

◆ 2.3 敏捷过程

敏捷方法假设项目成功的最重要因素是项目中人的素质,以及他们一起工作时人际关系有多好。使用什么过程和工具绝对是次要因素。

◆ 2.6 为过程裁剪UML

● 用例,描述人们如何与系统交互。
● 类图,从概念视角画类图,是建造严密的领域词汇表的好办法。
● 活动图,能够展示组织的工作流,展示软件如何与人类活动交互。活动图能够为用例展示其上下文,以及复杂用例的工作细节。
● 状态图,如果一个概念有一个有趣的生命周期,里面有各种状态和改变状态的事件,状态图很有用。

我经常发现我自己的设计经过编码以后,很难不做修改。我发现UML作为草稿依然很有用,但我没有发现它们可以是绝对正确的

文档中最重要的一项内容是你没有采纳的设计备选方案以及没有采纳的原因。这是你可以提供的外部文档中,经常最容易忘记、但最有用的部分。

◆ 第3章 类图:基础

类图(class diagram)描述系统中的对象类型,以及存在于它们之间的各种静态关系。

◆ 3.3 性质的编程解释

信息隐藏正是封装的本质。

在大多数情况下,你不给多值性质赋值;相反,你通过add和remove方法更新它。为了控制它的订单行条目性质,订单必须控制集合的成员;因此,它不应该将裸的集合传出。在这个例子里,我使用一个保护代理来给集合提供一件只读的外衣。你也可以提供一个不可更新的迭代器或者做一个副本。客户可以修改成员对象,但不应该直接改变集合本身。

◆ 3.5 操作

我经常发现辨别改变系统状态和不改变系统状态的操作很有用。UML把查询(query)定义为从类中取值而不改变系统状态的操作——换句话说,没有副作用。你可以用性质字符串{query}标记这样一个操作。我把改变状态的操作称为修改器(modifier),也称为命令。

◆ 3.8 依赖

我已发现表示和领域逻辑严格分离,表示依赖于领域,但反之不是,这是一条值得遵从的、有价值的规则。

基本的依赖不是可传递的关系

你的通用规则应该是最小化依赖,特别是依赖波及系统的大片面积时。特别是,你应该小心避免环状依赖,因为环状依赖会导致环状的改变。

尝试展示类图中的所有依赖是吃力不讨好的;因为有太多依赖而且改变太频繁。只有当依赖直接和你要沟通的特定主题相关时,才有选择地展示它们。为了理解和控制依赖,你最好只在包图上使用依赖(109页)

找到一个工具来做逆向工程,得到依赖图,是这里使用UML最有用的办法。

◆ 3.9 约束规则

画类图时,你正在做的大部分事情都是表明约束

关联、属性和泛化的基本构造已经详细描述了许多重要的约束,但它们还不能表达每一个约束。这些约束依然需要捕获;类图是做这件事情的好地方。

UML允许你使用任何东西来描述约束,唯一的规则是你要把它们放进花括号({})中。

按契约设计的核心是断言。断言(assertion)是一条决不应该为假的布尔陈述,因此,为假的唯一原因是存在bug。

契约设计使用3种特定的断言:后置条件、前置条件和不变式

类的不变式和后置条件必须应用于所有子类。子类可以选择加强这些断言,但不能减弱。另一方面,前置条件不能被加强,但可以被减弱。

◆ 第4章 序列图

有些人为所有调用使用返回,但我更喜欢只在能提供更多信息时使用;否则,它们只会把事情搞乱。

序列图不擅长于展示算法的细节,例如循环和条件行为,但它们使得参与者之间的调用十分清晰,并且很棒地勾勒出了哪个参与者做了哪些处理的画面。

好的设计的一个主要目标是把改变的影响局部化。数据和访问数据的行为经常一起改变。因此,把数据和使用它的行为放在一个地方,是面向对象设计的第一原则。

◆ 4.2 循环、条件等

我发现交互框非常笨拙,会使图的要点变得模糊,因此我更喜欢伪消息。

◆ 4.4 何时使用序列图

如果你要查看跨越许多用例的单个对象的行为,使用状态图(参见第10章)。如果你要查看跨越许多用例或许多线程的行为,考虑活动图(参见第11章)。

如果你要快速地探索多个多选一的交互,你最好使用CRC卡,这样可以避免许多绘制和擦除的工作。举行一个CRC卡会议来探索设计的可选方案通常很方便,然后再使用序列图捕获你在后面要引用的交互即可。

◆ 5.4 聚合和组合

通用规则是,虽然一个类可以是许多其他类的组件,但任何实例都必须是唯一拥有者的组件。类图可以展示多个类作为潜在的拥有者,但任何实例只能有单个对象作为它的拥有者。

“无分享”规则是组合的关键。另一个假设是,如果你删除Polygon,它应该自动地确保任何它所拥有的Point也被删除。

组合是展示按值拥有性质、值对象(91页)性质或者对于其他特定组件有强的排他的所有关系的性质的好办法

◆ 5.8 引用对象和值对象

随着时代的发展,引用对象和值对象之间的区别更加清晰了。值对象是类型系统的内建值。现在你可以用你自己的类扩展类型系统,因此这个问题需要进行更多的思考。

◆ 5.10 分类和泛化

我经常听到人们谈论,说子类型化为是一个(is a)关系,我极力主张在这么想的时候要小心,因为是一个可以有不同的含义。考虑以下语句。1.Shep是一只博德牧羊犬。2.一只博德牧羊犬是一只犬。3.犬是动物。4.一只博德牧羊犬是一个品种。5.犬是一个物种。现在尝试结合语句。如果我结合语句1和2,得到“Shep是一只犬”;结合语句2和3,得到“博德牧羊犬是动物”;结合1、2和3,得到“Shep是一只动物”。目前为止,一切都好。现在尝试结合语句1和4,得到“Shep是一个品种”。结合语句2和5,得到“博德牧羊犬是一个物种”这些就不那么合理了。为什么我可以结合一些语句,而不能结合另一些?原因是一些是分类(classification)——对象Shep是类型博德牧羊犬的一个实例——一些是泛化(generalization)——类型博德牧羊犬是类型犬的子类型。泛化是传递性的,分类则不是。可以在分类后跟着泛化,但反之不然。

◆ 5.11 多重和动态分类

在单个分类(single classification)中,对象属于单个类型,可能从超类型继承。在多重分类(multiple classification)中,对象可以由若干类型描述,这些类型未必通过继承连接。

多重分类不同于多重继承。多重继承说一个类型可以有许多超类型,但必须为每一个对象定义单个类型。多重分类允许一个对象有多个类型,不需要为此而定义一个特定的类型。

◆ 第9章 用例

用例(use case)是通过共同用户目标绑在一起的场景集合。

在用例的说法中,用户叫做执行者。执行者(actor)是用户扮演的跟系统相关的角色。

◆ 9.1 用例的内容

步骤应该展示执行者的意图,而不是执行者如何做的具体细节。因此,你不用在用例中描述用户界面。

用例结构是用头脑风暴法产生主成功场景的备选方案的很棒的办法

◆ 9.2 用例图

你在做用例时,不要花太多精力来画图。相反,应该将精力集中于用例的文本内容。

思考用例图的最佳途径是,把它看做用例集内容的图形目录。

集中于用例的文本描述,这是这项技能的真正价值所在。

◆ 9.3 用例的级别

海平面级别(sea-level)用例通常代表主执行者和系统之间独立的交互。

◆ 9.4 用例和特性(或故事)

通常,特性比用例有更细的粒度。

◆ 9.5 何时使用用例

重要的是,要记住用例表达系统的外部视图。所以,不要期望用例和系统内部的类之间有任何关联。

◆ 9.6 更多资料

重要性小得多的图标准化了。因此,你可以发现各种关于用例的有分歧的观点。然而,最近几年,[Cockburn,use cases]变成了

◆ 11.11 何时使用活动图

活动图的长处在于这样一个事实:支持和鼓励并行行为。

◆ 第12章 通信图

通信图(communication diagrams),交互图的一种,强调交互的各种参与者之间的数据链接。通信图不像序列图那样,把每一个参与者画成生命线并按垂直方向展示消息序列

3.读后感 & 点评

认为推荐
潘家宇老师翻译的,书中的内容也很不错

他不是那种大而全的 UML 标准说明书, 而是带着作者个人喜好个人使用 UML 风格的指导书,在讲解必要的图形符号时,会讲一些设计上的东西,是 UML 而不局限于 UML

如果你是带着要看 UML 工具书的目的来, 不推荐
如果你带着了解 UML ,想知道常用的 20% 怎么做的,推荐

4.相关资料