《UML和模式应用》学习笔记 - YoungBig

时间:2024-01-30 18:42:16

《UML和模式应用》学习笔记

#UML和模式应用
##一、绪论
### 第1章 面向对象分析和设计
#### 1.2 最重要的学习目标
在OO开发中,至关重要的能力是熟练地为软件对象分配职责

#### 1.3 什么是分析和设计
分析(analysis)强调的是对问题和需求的调查研究,而不是解决方案。

设计(design)强调的是满足需求的概念上的解决方案,而不是其实现。例如对数据库方案和软件对象的描述。

#### 1.4 什么是面向对象分析和设计
在面向对象分析(object-oriented analysis)过程中,强调的是在问题领域内发现和描述对象(或概念)。

在面向对象设计(object-oriented design)过程中,强调的是定义软件对象以及他们如何协作以实现需求。

#### 1.5 什么是UML
统一建模语言(UML)是描述、构造和文档化系统制品的可视化语言,UML定义了各种UML简档(UML profile),这些简档专用于某些常用主题领域的表示法子集,例如对EJB使用UML EJB文档。

**应用UML的三种方式**

- UML作为草图——非正式的、不完整的图。
- UML作为蓝图——相对详细的设计图,用于逆向工程或代码生成。
- UML作为编程语言——用UML完成软件系统可执行规格说明。可执行代码能够被自动生成(仍处于发展阶段)。

敏捷建模(agile modeling)强调了UML作为草图的方式,这也是使用UML的普通方式,而且通常对时间投入具有高回报。

**应用UML的三种透视图**

UML描述的是原始图类型,如类图和顺序图,它并没有在这些图上叠加建模的透视图。

- 概念透视图:用图来描述现实世界或关注领域中的事物。

- 规格说明(软件)透视图:用图来描述软件的抽象物或具体规格说明和接口的构建,但并不约定特定实现(例如非特定为C#或Java中的类)。

- 实现(软件)透视图:用图来描述特定技术(如Java)中的软件实现。

**不同透视图中“类”的含义**

- 概念类(conceptual class)——现实世界中的概念或事物。在概念或本质透视图中使用。UP领域模型中包含概念类。

- 软件类(software class)——无论在过程还是方法中,都表示软件构建在规格说明或实现透视图中的类。

- 实现类(implementation class)——特定OO语言(如Java)中的类。

### 第2章 迭代、进化和敏捷
迭代开发是OOA/D成为最佳实践的核心,也是OOA/D的核心。敏捷实践是有效应用UML的关键。UP是相对流行的、示范性的迭代方法

#### 2.1 什么是UP

软件开发过程(software development process)描述了构造、部署以及维护软件的方式。统一过程(Unified Process,UP)已经成为一种流行的构造面向对象系统的迭代软件开发过程。特别是Rational统一过程(Rational Unified Process,RUP)是对统一过程的详细精化,并且已经被广泛采纳。

UP把普遍认可的最佳实践结合起来,成为联系紧密并具有良好文档的过程描述。

#### 2.2 什么是迭代和进化式开发

迭代开发(iterative development)是UP和大多数其他现代方法中的关键实践。在这种生命周期方法中,开发被组织成一系列固定的短期(如三个星期)小项目,称为迭代;每次迭代都产生经过测试、集成并可执行的局部系统。每次迭代都具有各自的需求分析、设计、实现和测试活动。

迭代生命周期基于对经过多次迭代的系统进行持续扩展和精化,并以循环反馈和调整为核心驱动力,使之最终成为适当的系统。随着时间一次次迭代递进,系统增量式地发展完善,因此这一方法也被称为迭代和增量式开发(iterative and incremental development)。因为反馈和调整使规格说明和设计不断进化,所以这种方法也称为迭代和进化式开发(iterative and evolutionary development)。

迭代的输出不是实验性的或将丢弃的原型,迭代开发也不是构造原型,与之相反,其输出是最终系统的产品子集。

迭代的一个关键思想是时间定量(timeboxed),例如,假定选择下一次迭代时间为3周,则必须依照时间表来集成、测试和稳定局部系统——推迟时间则违约。

#### 2.3 什么是瀑布生命周期

在瀑布生命周期过程中,试图在编程之前(详细)定义所有或大部分需求。

准则:不要让瀑布思维侵蚀迭代或UP项目

#### 2.5 什么是风险驱动和客户驱动的迭代计划

UP提倡风险驱动(risk-driven)与客户驱动(client-driven)相结合的迭代计划。这意味着早期的迭代目标要能够识别和减低最高风险,并且能构造客户最关心的可视化特性。风险驱动迭代开发更为明确地包含了以架构为中心迭代开发的实践,意味着早期迭代要致力于架构的构造、测试和稳定。因为没有稳定的架构就会带来高风险。

#### 2.10 什么是UP的阶段和UP科目

UP项目将其工作和迭代组织为四个主要阶段:

- 初始(Inception):大体上的构想、业务案例、范围和模糊评估。
- 细化(Elaboration):已精化的构想、核心架构的迭代实现、高风险的解决、确定大多数需求和范围以及进行更为实际的评估。
- 构造(Construction):对遗留下来的风险较低和比较简单的元素进行迭代实现,准备部署。
- 移交(Transition):进行bata测试和部署。

UP描述了科目(discipline)中的工作活动,例如编写用力。科目是在一个主题域中的一组活动(及相关制品),例如需求分析中的活动。在UP中,制品(artifact)是对所有工作产品的统称,如代码、Web图形、数据库模式、文本文档、图、模型等。

### 第3章 案例研究

**为什么要重点探讨核心应用逻辑层的OOA/D**

通常,应用包括UI元素、核心应用逻辑、数据库访问以及外部软硬构件的协作

- 其它层通常对技术/平台有极大的依赖性
- 核心逻辑层的OO技术对各种技术来说是相似的
- 基本OO设计技巧适用于所有其他层或构件
- 当新框架或技术出现时,其它层的设计方法和模式呈现出加速变化的趋势

##二、初始阶段
###第4章 初始不是需求阶段

#### 4.1 什么是初始阶段

**项目起始步骤思考**

- 项目的设想和业务案例是什么?
- 是否可行?
- 购买还是开发?
- 粗略估计一下成本?
- 项目继续还是停止?

初始阶段的目标并不是定义所有需求,或产生可信的预算或项目计划

大多数需求分析是在细化阶段进行的,并且伴以具有产品品质的早期编程和测试

初始阶段只需确定这个项目是否值得认真研究,而不是去深入的进行研究

**概括初始阶段:预见项目的范围、设想和业务案例**

**要解决的主要问题:涉众是否就项目设想基本达成一致,项目是否值得继续进行认真研究**

#### 4.3 初始阶段会创建的制品

1. 设想和业务用例
2. 用例模型:确定大部分用例名称,详细分析10%的用例
3. 补充性规格说明:关键的非功能性需求
4. 词汇表
5. 风险列表和风险管理计划
6. 原型和概念验证
7. 迭代计划
8. 阶段计划和软件开发计划
9. 开发案例

###第5章 进化式需求

#### 5.2 进化式需求与瀑布式需求

UP的需求管理定义中使用了“不断变更”一词。UP能够包容需求中的变更,并将其作为项目的基本驱动力。这是迭代和进化式思想和瀑布思想的**核心差异**

#### 5.4 需求的类型和种类

**“FURPS+”模型分类**

- 功能性(Functional):特性、功能、安全性
- 可用性(Usability):人性化因素、帮助、文档
- 可靠性(Reliability):故障频率、可恢复性、可预测性
- 性能(Performance):响应时间、吞吐量、准确性、有效性、资源利用率
- 可支持性(Supportability):适应性、可维护性、国际化、可配置性

“FURPS+”中“+”是指一些辅助性的和次要的因素,比如:

- 实现(Implementation):资源限制、语言和工具、硬件等
- 接口(Interface):强加于外部系统接口之上的约束
- 操作(Operation):对其操作设置的系统管理
- 包装(Packaging):例如物理的包装盒
- 授权(Legal):许可证或其他方式

#### 5.5 UP制品如何组织需求

**关键制品(可选)**

- 用例模型:一组使用系统的典型场景,主要用于功能需求
- 补充性规格说明:用例之外的所有内容,主要用于非功能需求
- 词汇表:以最简单的形式定义重要的术语。同时包含了数据字典
- 设想:概括了高阶需求
- 业务规则:通常描述了凌驾于某一软件项目的需求或政策

###第6章 用例

**用例是文本形式的情节描述**。用以说明某参与者使用系统以实现某些目标。用例不是图形,而是文本。很多人在内常见的错误就是注重次要的UML用例图,而非重要的用例文本。

#### 6.2 定义:参与者、场景和用例

参与者(actor):某些具有行为的事物,比如 人、计算机系统或组织

场景(scenario):参与者和系统之间的一系列特定活动和交互,也称作用例实例

用例(use case):是一组相关的成功和失败场景集合

#### 6.4 动机:为什么使用用例

**用例的价值**

- 用例是一种优秀的方法,使定义和评审更加简单
- 用例强调了用户的目标和观点。可以解答以下几个问题
    - 谁使用系统?
    - 他们使用的典型场景是什么?
    - 他们的目的是什么? 

#### 6.8 示例

**详述用例模板**

1. 用例名称:以动词开始
2. 范围:要设计的系统
3. 级别:“用户目标”或者是“子功能”
4. 主要参与者:调用系统,使之交付服务
5. 涉众及其关注点:关注该用例的人
6. 前置条件:值得告知的,开始前必须为真的条件
7. 成果保证:值得告知的,成功完成必须满足的条件
8. 主成功场景:典型的、无条件的、理想方式的成功场景
9. 扩展:成功或失败的替代场景
10. 特殊需求:相关的非功能性需求
11. 技术和数据变元表:不同的I/O方法和数据格式
12. 发生频率:影响对实现的调查、测试和时间安排
13. 杂项:例如未决问题

#### 6.11 准则

**编写用例的准则**

- 以无用户界面约束的本质风格编写用例
- 编写简洁的用例
- 编写黑盒用例:通过职责来描述系统
- 采用参与者和参与者目标的观点
- 如何发现用例
    1. 选择系统边界。系统仅仅是软件应用,还是将硬件和应用作为整体?十一个人使用,还是整个组织在使用?
    2. 确定主要参与者——通过使用系统的服务实现其目标的那些人或事物。
    3. 确定每个主要参与者的目标。
    4. 定义满足用户目标的用例,根据其目标对用例命名。通常,用户目标级别的用例和用户目标是一一对应的。

#### 6.17 应用UML:用例图

**用例图和用例关系在编写用例工作中是次要的。用例是文本文档。编写用例意味着编写文本。**

制图准则:**不要倚重于制图,保持其简短**

###第7章 其他需求

UP是一种迭代和进化式方法,意味着应该早在完整地分析和记录大多数需求之前,尽早进行具有产品品质的编程和测试。来自早期编程和测试的反馈使需求进化

在开始阶段,高阶粗粒度需求的“前十”列表是由帮助的

##三、细化迭代1——基础

###第8章 迭代1——基础

#### 8.1 迭代1的需求和重点:OOA/D技术的核心

在迭代开发中,并非一次就实现所有需求,在多个迭代里对同一用例进行增量式开发

#### 8.2 过程:初始和细化

**初始阶段发生了什么?**

- 简短的需求讨论会
- 大多数参与者、目标和用例名称
- 大多数以摘要形式编写的用例
- 确定大多数具有影响和风险的质量需求
- 编写设想和补充性规格说明的第一个版本
- 风险列表
- 技术上的概念验证原型和其他调查
- 面向用户界面的原型
- 对购买/构建/复用构件的建议
- 对候选的高层架构和构件给出了建议
- 第一次迭代的计划
- 候选工具列表

**细化阶段目标**

- 对核心、有风险的软件架构进行编程和测试
- 发现并稳定需求的主体部分
- 规避主要风险

细化核心:**构建核心架构,解决高风险元素,定义大部分需求,以及预计总体进度和资源**

**细化阶段要做什么?**

- 实行短时间定量、风险驱动的迭代
- 及早开始编程
- 对架构的核心和风险部分进行适应性的设计、实现和测试
- 尽早、频繁、实际地测试
- 基于来自测试、用户、开发者的反馈进行调整
- 通过一系列讨论会,详细编写大部分用例和其他需求,每个细化迭代举行一次

###第9章 领域模型

#### 9.2 什么是领域模型

领域模型(domain model)是对领域内的概念类或现实世界中对象的可视化表示。领域模型也称为概念模型、领域对象模型和分析对象模型。

在UP中,术语“领域模型”指的是对现实世界概念类的表示,而非软件对象的表示。该术语并不是指用来描述软件类、软件架构领域层或有职责软件对象的一组图。UP对领域模型的定义是可以在业务建模科目中创建的制品之一。更准确地讲,UP领域模型是UP业务对象模型的特化。

**什么是概念类?**

通俗的说,概念类是思想、事物或对象。更正式的讲,概念类可以从其符号、内涵和外延来考虑。

- 符号:表示概念类的词语或图形
- 内涵:概念类的定义  
- 外延:概念类所适用的一组示例

#### 9.4 如何创建领域模型

以当前迭代中所要设计的需求为界:

1. 寻找概念类
2. 将其绘制为UML类图中的类
3. 添加关联和属性。

**如何找到概念类?**

找到概念类的三条策略

1. 重用和修改现有的模型
2. 使用分类列表
3. 确定名词短语

#### 9.14 关联

关联(association)是类(更准确的说,是这些类的实例)之间的关系,表示有意义和值得关注的连接。在UML中,关联被定义为“两个或多个类元之间的语义联系,涉及这些类元实例之间的连接”。

**准则:何时表示关联**

在领域模型中要考虑如下关联:

如果存在需要保持一段时间的关系,将这种语义表示为关联。  
从常见关联列表中派生的关联。
  
#### 9.16 属性

是对象的逻辑数据值。

**准则:何时展示属性**

当需求建议或暗示需要记住信息时,引入属性。

#### 9.18 结论:领域模型是否正确

没有所谓唯一正确的领域模型。所有模型都是对我们试图要理解的领域的近似。领域模型主要是在特定群体中用于理解和沟通的工具。有效的领域模型捕获了当前需求语境下的本质抽象和理解领域所需要的信息,并且可以帮助人们理解领域的概念、术语和关系。

###第10章 系统顺序图

#### 10.2 什么是系统顺序图

系统顺序图(SSD)是为阐述与所讨论系统相关的输入和输出事件而快速、简单地创建的制品

系统顺序图表示的是,对于用例的一个特定场景,外部参与者产生的事件,其顺序和系统之内的时间。所有的系统被视为黑盒。此图强调的是从参与者到系统的跨越系统边界的事件。

SSD不是UML里的顺序图,UML顺序图作为表示方法,阐述了参与者的交互以及参与者引发的操作

**准则:应为每个用例的主成功场景,以及频繁发生的或者复杂的替代场景绘制SSD。**

#### 10.3 为什么要绘制SSD

软件设计中一个有趣且有用的问题是:我们系统中会发生什么事件?为什么?因为我们必须为处理和响应这些事件(来自于鼠标、键盘、和其他系统---)来设计软件。基本上,软件系统要对以下三种事件进行响应:1)来自于参与者(人或计算机)的外部事件,2)时间事件,3)错误或异常(通常来源于外部)。因此,需要准确的知道,什么是外部输入事件,即系统事件。

#### 10.5 SSD和用例之间的关系

SSD展示了用例中一个场景的系统事件,因此它是从对用例的考察中产生的。

#### 10.10 过程:迭代和进化式SSD

SSD是用例模型的一部分,将用例场景隐含的交互可视化

UP阶段:

初始——通常不会在该阶段引入SSD

细化——大部分SSD在细化阶段创建

###第11章 操作契约

在UP中,用例和系统特性是用来描述系统行为的主要方式,足够满足需求。有时需要对系统行为进行更加详细和精确的描述。操作契约使用前置和后置条件的形式,描述领域模型里对象的详细变化,并作为操作系统的结果

#### 11.2 契约有哪些部分

**操作契约包括以下部分:**

- 操作:操作的名称和参数。
- 交差引用:会发生此操作的用例。
- 前置条件:执行操作之前,对系统或领域模型对象状态的重要假设。这些假设比较重要,应该告诉读者。
- 后置条件:最重要的部分。完成操作后,领域模型对象的状态。

#### 11.3 什么是系统操作

可以为系统操作定义操作契约,系统操作是作为黑盒构件的系统在其公共接口中提供的操作。

#### 11.4 后置条件

后置条件描述了领域模型内对象状态的变化。

后置条件不是在操作过程中执行的活动,而是对领域模型对象的观察结果

#### 11.7 契约在何时有效

在UP中,用例是项目需求的主要知识库。用例可以为设计提供大部分或全部所需细节。但是当所需状态变化的细节和复杂度难以处理或过于细节化时,需要用到契约

#### 11.8 如何创建和编写契约

**创建契约**

1. 从SSD中确定系统操作
2. 如果系统操作复杂,其结果可能不明显,或者在用例中不清楚,则可以为其构造契约
3. 使用以下几种类别来描述后置条件:
    - 创建和删除实例
    - 修改属性
    - 形成和清除关联

**编写契约**

- 以说明性的、被动式的过去时态编写后置条件,强调变化的观察结果
- 要在已有或新创建的对象之间建立关联

###第12章 从需求到设计——迭代进化

#### 12.1 以迭代方式做正确的事,正确地做事

需求和面向对象分析重点关注学习做正确的事。要理解案例分析中的一些重要目标,以及相关的规则和约束。后续的设计工作将强调正确地做事,即熟练地设计解决方案来满足本次迭代的需求

#### 12.2 尽早引发变更

尽早编程、测试和演示有助于尽早引发不可避免的变更

###第13章 逻辑架构和UML包图

#### 13.2 什么是逻辑架构和层

逻辑架构(logical architecture)是软件类的宏观组织结构,它将软件类组织为包(或命名空间)、子系统和层等。之所以称其为逻辑架构,是因为并未决定如何在不同的操作系统进程或网络中物理的计算机上对这些元素进行部署。

层(layer)是对类、包或子系统的甚为粗粒度的分组,具有对系统主要方面加以内聚的职责。同时、层按照较高层(例如UI层)可以调用较低层的服务,而反之则不然的方式组织。

**OO系统中通常包括的层有:**

- 用户界面
- 应用逻辑和领域对象——表示领域概念的软件对象
- 技术服务——提供支持性技术服务的常用对象和子系统,例如数据库接口或错误日志。
  
#### 13.6 准则:使用层进行设计

本质思想:

- 将系统的大型逻辑结构组织为独立的、职责相关的离散层,具有清晰、内聚的关注分离
- 协作和耦合是从较高层到较低层进行的,要避免从较低层到较高层的耦合

**准则:内聚职责,使关系分离**

同一层内的对象在职责上应该具有紧密关联,不同层中对象的职责则不应该混淆。

**准则:不要将外部资源表示为最底层**

将外部资源(如某个数据库)表示为“低于”基础层的层,是对逻辑视图和架构部署视图的混淆

就逻辑架构及其层而言,对某个持久数据集合(如库存数据)的访问可以视为领域层中的子领域——库存子领域。而提供数据库访问的一般性服务则可以视为技术服务分区——持久性服务

#### 13.7 准则:模型-视图分离原则

1. 不要将非UI对象直接与UI对象连接或耦合。
2. 不要在UI对象方法中加入应用逻辑。

#### 13.8 SSD、系统操作和层之间的联系

SSD描述了系统操作,但是隐藏了特定的UI对象。然而,捕获系统操作请求的对象通常是系统UI层的对象。设计良好的分层架构支持高内聚和关系分离,UI层对象将从UI层向领域层转发请求以进行处理。

从UI层发送到领域层的消息将是SSD中所描述的消息。

#### 第14章 迈向对象设计

**开发者如何设计对象?一般采用如下三种方式:**

1. 编码。在编码的同时进行设计(java、C#、---),更为理想的是使用诸如再工程(refactoring)这样的强大工具。根据想象的模型直接编码。
2. 绘图,然后再编码。在白板或UML CASE工具中绘制一些UML,然后转到第一种方式,使用文本增强型集成开发环境(IDE,如Eclipse或Visual Studio)进行编码。
3. 只绘图,不编码。使用工具从图中生成一切。“只绘图”是不当之词。因为实际上还是会在UML图形元素上附加文本的编程语言。

一些敏捷建模的目标是减少常用图形,建模的目的是为理解和沟通而不是构建文档。可以尝试简单的敏捷建模方法——“UML草图”。一般中小公司都采用这种方式,而大公司都有很严格的UML制品。

#### 14.4 设计对象:什么是静态和动态建模

**对象模型有两种类型:动态和静态。**

动态模型有助于设计逻辑、代码行为或方法体,例如UML交互图(顺序图或通信图)。注:这里的顺序图是UML顺序图,并非是上一篇文章中的系统顺序图(SSD)。动态模型倾向于创建更为有益、困难和重要的图形。

静态模型有助于设计包、类名、属性和方法特征标记(但不是方法体)的定义,例如UML类图。

静态和动态建模之间具有关系,敏捷建模对此的实践是并行创建模型:花费较短的时间创建交互图(动态),然后转到对应的类图(静态),交替进行。

- 动态对象建模

    UML初学者(包括我)一般会认为静态视图的类图是重要图形,但事实上。大部分具有挑战性、有益和有效的设计工作都会在绘制UML动态视图的交互图的时候发生。需要哪些对象,它们是徒河通过消息和方法进行协作,通过动态对象建模(例如绘制顺序图)才能真正落实这些准确和详细的结论。

    **准则:应该把时间花费在交互图(顺序图或通信图),而不仅仅是类图上。忽视这一准则是十分常见的UML错误实践。**

    注意:在应用职责驱动设计和GRASP原则的动态建模过程中,这一准则尤其重要。在第一篇文章也提到,这里又出现了,索性这里先稍微解释一下.所谓的职责驱动设计,简单地说就是职责必须匹配。什么是职责呢?简单地说,一个类或构件的职责包括两个方面:一个是指导的事,对于一个类来说就是他的属性;一个是能做的事,对于一个类来说就是他的方法(来自百度百科)。虽然看上去不是很严谨,但可以通俗理解了职责驱动设计是以职责为中心。关于职责驱动设计和GRASP会在后续文章详细讨论。

- 静态对象建模

    最常见的静态对象建模是使用UML类图。注意:如果开发者应用了并行创建若干模型的敏捷建模实践,则他们应该同时绘制交互图和类图。

#### 14.5 基于UML表示法技术的对象设计技术的重要性

**重要的是以对象进行思考和设计,并且应用对象设计的最佳实践模式,这与了解UML表示法极为不同,并且更有价值**


**对象设计技能与UML表示法技能**

1. 绘制UM反映了对设计做出的决策。
2. 对象设计技术并不一定要了解如何绘制UML
3. 基本的对象设计需要了解的是:
    - 职责分配原则
    - 设计模式

### 第15章 UML交互图

UML使用交互图来描述对象间通过消息的交互。交互图可以用于动态对象建模。交互图有两种类型:顺序图和通信图。

静态视图类图确实有效,但动态视图的交互图(确切说是动态交互建模中的动作)的价值更高

**顺序图与通信图的优点和缺点**

顺序图在某些地方优于通信图。UML规范更多是以顺序图为核心,采用顺序图可以更方便的表示调用流的顺序,仅需要由上至下阅读即可。而对于通信图,我们必须查阅顺序编号

顺序图:

- 优势:能够清晰表示消息的顺序和时间排序
- 劣势:强制在右侧增加新对象;消耗水平空间

通信图:

- 优势:空间效用——能够在二维空间内灵活的增加新对象
- 劣势:不易查阅消息的顺序


### 第16章 UML类图                             

UML用类图表示类、接口及其关联。类图用于静态对象建模。

#### 16.2 定义:设计类图

同一种UML图可以用于多种透视图,在概念透视图里,类图可以用于将领域模型可视化。为了区分使用在软件透视图和设计透视图中的类图,常用的建模术语是设计类图(Design Class Diagram, DCD)

#### 16.3 定义:类元

UML类元是描述行为和结构特性的模型元素,包括类、接口、用例和参与者。

#### 16.21 交互图和类图之间的关系

当我们绘制交互图时,在此动态对象建模的创造性设计过程中会产生一组类及其方法。因此,类图的定义能够从交互图中产生。这表明一种线性的顺序,即先绘制交互图,再绘制类图。但是在实践中,尤其是应用了并行建模的敏捷建模实践后,这些互补的动态视图和静态视图是并行创建的。例如,10分钟绘制静态视图,10分钟绘制动态视图,交替进行。

### 第17章 GRASP:基于职责设计对象

#### 17.1 UML与设计原则

UML只是一种标准的、可视化建模语言。

**最关键的软件开发工具时受过良好设计原则训练的思维,而不是UML或任何其他技术**

#### 17.2 对象设计:输入、活动和输出的示例

- 这是对前面章节的总结:

    到目前阶段,已经经历了以下内容:

    1. 第一个需求讨论会:准备实现和测试某些用例的场景
    2. 开始编程前,已经详细分析了10%到20%的需求;其他制品已经启动(补充规格说明、术语表和领域模型)
    3. 编程实验已经解决了“演示阻塞”的技术问题;总架构师已经利用UML包图提出了大型逻辑架构的构思

    已经有以下制品:

    1. 用例文本
    2. 系统顺序图
    3. 操作契约
    4. 补充规格说明
    5. 词汇表
    6. 领域模型

- 接下来的工作:从分析师转换为设计者和建模者

    有三个选择:1. 立即开始编码, 2. 开始为对象设计进行一些UML建模, 3. 利用其它建模技术
    
    如果选择2,是不是UML并不重要,重要的是可视化建模

    **绘制模型主要是为了理解和沟通,并不是为了编写文档,不要再编程之前进行过度建模(不要花太多时间在建模上)**
    
- 输出

    1. 对于对象设计而言,开始编程前针对设计中的难点创建UML交互图、类图和包图
    2. UI草图和原型
    3. 数据库模型
    4. 报表的草图和原型

#### 17.3 职责和职责驱动设计

思考软件对象设计以及大型构件的流行方式是:**考虑其职责、角色和协作**。这是被称为职责驱动设计(RDD)的大型方法的一部分

OO设计总得来说,是基于职责驱动设计所代表的内在含义是考虑怎样给协作中的对象分配职责。

在RDD中,我们人物软件对象具有职责,即对其所作所为的抽象。就对象的角色而言,职责与对象的义务和行为相关。

职责分为以下两种类型:

- 行为职责
    1. 自身执行的一些行为,如创建对象或计算。
    2. 初始化其他对象中的动作。
    3. 控制和协调其他对象中的活动。    
- 认知职责
    1. 对私有封装数据的认知。
    2. 对相关对象的认知。
    3. 对其能够导出或计算的事物的认知。

在对象设计中,职责被分配给对象类。例如,我可以声明“Sale负责创建SalesLineItems”(行为职责),或“Sale负责认知其总额”(认知职责)。

准则:对于软件领域对象来说,由于领域模型描述了领域对象的属性和关联,因此其通常产生与“认知”相关的职责。

职责与方法并非同一事物,职责是一种抽象,而方法实现了职责。

RDD也包括了协作的思想。职责借助于方法来实现,该方法既可以单独动作,也可以与其他方法和对象协作。RDD是一种隐喻。RDD是思考OO软件设计的一般性隐喻。把软件对象想象成具有某种职责的人,他要与其他人协作完成工作。RDD使我们把OO设计看做是有职责对象进行协作的共同体。

关键点:GRASP对一些基本的职责分配原则进行了命名和描述,因此掌握这些原则有助于支持RDD。

#### 17.4 GRASP:基于OO设计的系统方法

GRASP:使用职责进行OO设计的学习工具

GRASP原则或模式是一种学习工具,它能帮助你理解基本对象设计,并且以一种系统的、合理的、可以理解的方式来运用设计推理。对这种设计原则进行理解和使用的基础是分配职责的模式。

#### 17.5 职责、GRASP和UML图之间的联系

当我们在绘制UML交互图时,就是在决定职责的分配。

#### 17.6 什么是模式

有经验的OO开发者建立了既有通用规则又有惯用方案的指令系统来指导他们编制软件,如果以结构化形式对这些问题、解决方案和命名进行描述使其系统化,那么这些原则和习惯用法就称为模式。

**GRASP是一组模式或原则吗?**

GRASP定义了9个基本OO设计原则或基本设计构件,其描述的是原则而不是模式。模式是一种优秀的学习工具,可以用来命名、表示和记忆那些基本和经典的设计思想。

**GRASP的9个模式:**

- 创建者(Create)
- 控制器(Controller)是UI层之上的第一个对象,它负责接收和处理系统操作消息。
- 纯虚构(Pure Fabrication)
- 信息专家(Information Expert)
- 高内聚(High Cohesion)
- 间接性(Indirection)
- 低耦合(Low Coupling)
- 多态性(Polymorphism)
- 防止变异(Protected Variantions)

#### 17.10 创建者

以下的条件之一(越多越好)为真时,将创建类A实例的职责分配给类B:

- B“包含”或组成聚集A
- B记录A
- B直接使用A
- B具有A的初始化数据,并且在创建A时会将这些数据传递给A
- B是对象A的创建者

#### 17.11 信息专家(或专家)

**给对象分配职责的基本原则是什么?**

把职责分配给信息专家,它具有实现这个职责所必需的信息。

1. 分配职责应当从清晰地描述职责开始。
2. 如果在设计模型中存在相关的类,首先查看设计模型
3. 否则查看领域模型,并且尝试利用(或扩充)它的表示,以激发相应设计类的创建

#### 17.12 低耦合

**怎样降低依赖性,减少变化带来的影响,提高重用性?**

分配职责,使耦合性尽可能低。利用这一原则来评估可选方案

#### 17.13 控制器

控制器是UI层之上的第一个对象,它负责接收和处理系统操作消息

### 第18章 使用GRASP的对象设计示例

#### 18.1 什么是用例实现

用例实现描述了某个用例基于协作对象如何在设计模型中实现。用例实现是UP术语,用以提示我们在表示为用例的需求和满足需求的对象之间的联系

#### 18.6 过程:迭代和进化式对象设计

**UP中的对象设计**

**初始**——不到细化阶段,通常不会开始设计模型和用例实现的设计

**细化**——该阶段中,可能要为设计中大部分在架构上重要的或有风险的场景创建用例实现。不需要所有场景,也不需要完整和细粒度的细节

**构造**——为当前存在的设计问题构造用例实现

#### 18.7 总结

设计对象交互和职责分配是对象设计的核心。这些设计决策对对象软件系统是否清晰、是否具有扩展性和可维护性具有重大影响,同时也对构建复用的程度和质量具有影响。职责分配可以遵循一定的原则,GRASP模式总结了面向对象设计最常用的原则

### 第19章 对可见性进行设计

**可见性的四种方式:**

- 属性可见性:B是A的属性
- 参数可见性:B是A中方法的参数
- 局部可见性:B是A中方法的局部对象
- 全局可见性:B具有某种方式的全局可见性

### 第21章 测试驱动开发和重构

极限编程(XP):首先编写测试;不断重构代码以改进质量,包括降低冗余、提高清晰度等

#### 21.1 测试驱动开发

测试驱动开发(TDD)是迭代和敏捷XP方法提倡的优秀实践。

关键点:首先编写测试,再编写预计要测试的代码

**TDD优点**

- 能够保证编写单元测试
- 使程序员获得满足感从而更始终如一地坚持编写测试
- 有助于澄清接口和行为的细节
- 可证明、可再现、自动的验证
- 改变事物的信心

#### 21.1 重构

重构是重写或重新构建已有代码的结构化和规律性方法,但不会改变已有代码的外在行为,而是采用一系列少量转换的步骤,并且每一步都结合了重新执行的测试

### 第22章 UML工具和UML蓝图

#### 22.1 前向、逆向和双向工程

前向工程是从图形生成代码

逆向工程是从代码生成图形

双向工程是以上两种工程的闭环

##四、细化迭代2——更多模式

### 第23章 迭代2:更多模式

#### 23.1 从迭代1到迭代2

迭代1结束的时候,应该已经完成了以下任务:

- 所有软件都已经被充分地测试:单元、验收、负载、可用性等。
- 客户定期地参与对已完成部分的评估,从而使开发人员获得对调整和澄清需求的反馈
- 已经对系统进行了完整的集成和固化(基础版本)

#### 23.2 迭代2的需求和重点:对象设计和模式

迭代2很大程度上忽视了案例研究和需求分析和领域分析,而是着重于使用职责和GRASP进行对象设计,并且应用一些GoF设计模式

### 第24章 快速地更新分析

使用UP的过程成熟标志是:知道何时创建制品能够带来显著价值,或者当遇到呆板的“完成作业”式的步骤时能够较好的略过

**当有下列情况时,创建超类的概念子类:**

1. 子类具有我们感兴趣的额外属性
2. 子类具有我买个感兴趣的额外关联
3. 对子类概念的影响、处理、反应和操作与超类或其他子类有显著的差异

### 第25章 GRASP:更多具有职责的对象

#### 25.1 多态

当相关选择或行为随类型(类)有所不同时,使用多态操作为变化的行为类型分配职责。推论:不要测试对象的类型,也不要使用条件逻辑来执行基于类型的不同选择

**准则:何时使用接口进行设计**

多态意味着在大部分OO语言中要使用抽象超类或接口。何时应该考虑使用接口呢?普遍答案是:当你想要支持多态但又不想约束于特定的类层次结构时,可以使用接口。如果使用了抽象超类AC而不是接口,那么任何新的多态方案都必须是AC的子类,这对于诸如Jave和C#的单根继承语言来说将十*限。经验做法是,如果有一个具有抽象超类C1的类层次结构,可以考虑对应于C1中的公共方法特征标记来定义接口I1, 然后声明C1来实现接口I1,。这样,对于新的多态方案,即使没有避免使用C1子类的直接动机,也能够获得灵活的进化点,用来应对将来未知的情况

**优点**

- 易于增加新变化所需的扩展
- 无需影响客户便能够引入新的实现

#### 25.2 纯虚构

对人为制造的类分配一组高内聚的职责,该类不代表问题领域的概念——虚拟的事物,用以支持高内聚、低耦合和复用

这种类是凭空虚拟的,理想状态下,分配给这种虚拟物的职责要支持高内聚和低耦合,使这种虚拟物清晰或纯粹,因此称为纯虚构

#### 25.3 间接性

**为了避免多个事物之间直接耦合,应该如何分配职责?**

将职责分配给中介对象,使其作为其他构件或服务之间的媒介,以避免它们之间的直接耦合。中介实现了其他构件之间的间接性

#### 25.4 防止变异

**如何设计对象、子系统和系统,使其内部的变化或不稳定性不会对其他元素产生不良影响?**

识别预计变化或不稳定之处,分配职责用以在这些变化之外创建稳定接口

### 第26章:应用GoF设计模式

#### 26.1 适配器(GoF)

问题:如何解决不相容的接口问题,或者如何为具有不同接口的类似构件提供稳定的接口?

方案:通过中介适配器对象,将构件的原有接口转换为其他接口

#### 26.4 工厂(Factory)

**优点**

- 分离复杂创建的职责,并将其分配给高内聚的帮助者对象
- 隐藏潜在的复杂创建逻辑
- 允许引入提高性能的内存管理策略,例如对象缓存或再生

#### 26.5 单实例类(GoF)

问题:只有唯一实例的类即为“单实例类”,对象需要全局可见性和单店访问

方案:对类定义静态方法用以返回单实例

#### 26.7 策略(GoF)

问题:如何设计变化但相关的算法或政策?如何设计才能使这些算法或政策具有可变更的能力?

方案:在单独的类中分别定义每种算法/政策/策略,并且使其具有共同接口

#### 26.8 组合(GoF)和其他设计原则

问题:如何能够像处理非组合(原子)对象一样,(多态地)处理一组对象或具有组合结构的对象呢?

方案:定义组合和原子对象的类,使它们实现相同的接口

#### 26.9 外观(GoF)

问题:对一组完全不同的实现或接口需要公共、统一的接口。可能会与子系统内部的大量事物产生耦合,或者子系统的实现可能会改变,怎么办?

方案:对子系统定义唯一的接触点——使用外观对象封装子系统。该外观对象提供了唯一和统一的接口,并负责与子系统构件进行协作

#### 26.10 观察者/发布—订阅/委派事件模型(GoF)

名称:观察者(Observer)(发布-订阅(Publish-Subscribe)

问题:不同类型的订阅者对象关注于发布者对象的状态变化或事件,并且想要在发布者产生事件时以自己独特的方式作出反应。此外,发布者想要保持与订阅者的低耦合。如何设计?

方案:定义“订阅者”或“监听者”接口。订阅者实现此接口。发布者可以动态注册关注某事件的订阅者,并在事件发生时通知它们

##五、细化迭代3——中级主题

### 第27章 迭代3——中级主题

迭代3涉及的主题比较宽泛,将探讨各种分析和设计主题:

- 更多GoF设计模式及其在设计中的应用
- 架构分析,使用N+1视图模型对架构建立文档
- 使用UML活动图对过程进行建模
- 泛化和特化
- 包的设计

### 第28章 UML活动图及其建模

特别说明

- 一旦某个动作完成,紧接着会有一个自动的向外转换
- 活动图能够即表示控制流又表示数据流

#### 28.4 准则

- 活动图通常对于涉及众多参与者的非常复杂的业务过程建模具有价值,对于简单的业务过程,用例文本就够用了
- 在进行业务过程建模时,可以利用rake符号和子活动图。在level 0图的概览中,保持较高的抽象水平,从而使图形具有清晰、简洁的品质。在level 1,甚至可能是level 2的子图中扩展细节
- 尽量保持一张图中所有动作节点的抽象水平一致

### 第29章 UML状态机图和建模

UML状态机图描述了某个对象的状态和感兴趣的事件以及对象响应该事件的行为

#### 29.2 定义:事件、状态和转换

事件:一件值得注意的事情的发生,如:电话接线员拿起话筒

状态:对象在事件发生之间某时刻所处的情形,如电话接听时处于“active”状态

转换:两个状态之间的关系

#### 29.3 如何应用状态机图

准则:考虑为具有复杂行为的状态依赖对象而不是状态无关对象建立状态机图

准则:对操作协议和语言规范的合法序列建模

### 第30章 用例关联

准则:避免陷入用例关系的陷阱

不要花费过多时间争论在用例图中如何关联用例,而没有关注更重要的工作:编写用例文本

### 第31章 领域模型的精化

#### 31.2 泛化

泛化是在多个概念中识别共性和定义超类与子类关系的活动

准则:识别领域中与本次迭代有关的超类和子类,并且在领域模型中阐明

#### 31.4 何时定义概念子类

1. 子类有额外的有意义的属性
2. 子类有额外的有意义的关联
3. 子类概念的操作、处理、反应或使用的方式不同于其超类或其他子类,而这些方式时我们关注的
4. 子类概念表示了一个活动题,其行为与超类或者其他子类不同,而这些行为是我们关注的

#### 31.5 何时定义概念超类

1. 潜在的概念子类表示的是相似概念的不同变体
2. 子类满足100%和Is-a规则
3. 所有子类都具有相同的属性,可以将其解析出来并在超类中表达
4. 所有子类都具有相同的关联,可以将其解析出来并于超类关联

#### 31.7 抽象概念类

如果类C的每个成员也必须是某个子类的成员,则类C被称为抽象概念类

#### 31.8 对变化的状态建模

不要将概念X的状态建模为X的子类。有两个办法可供选择:

- 定义状态类层次结构,并将其与类X关联
- 在领域模型中忽略概念的状态,而在状态图中加以反映

#### 31.18 使用包类组织领域模型

将领域模型划分为包结构时,将满足下述条件的元素放在一起:

- 在同一个主题领域,概念或目标密切相关的元素
- 在同一个类层次结构中的关系
- 参与同一个用例的元素
- 有很强的关联性的元素

### 第32章 更多SSD和契约

SSD将每个系统当做“黑箱”,使用顺序图阐释系统之间的交互。在SSD中阐述新的系统事件有利于说明下述问题:

- 系统需要支持的新的系统操作
- 对其他系统的调用以及期望得到的响应

### 第33章 架构分析

架构分析可以被视为需求分析的规格化,其关注强烈影响“架构”的需求

架构分析的本质是要识别影响架构的因素,理解这些因素的可变性和优先级,并且解决这些问题。

**为什么架构分析如此重要,因为它有助于:**

- 降低在系统设计中丢失某些重要因素的风险
- 避免在低优先级的问题上花费过多的精力
- 有助于产品与业务目标的一致

#### 33.2 定义:变化点和进化点

变化点(variation point)- 当前现有系统或需求中的变化之处,例如:必须支持的多个税金计算器接口

进化点(evolution point)- 现有需求中不存在、但可能在将来发生,推测性的变化点。

变化点和进化点是在架构分析中反复出现的关键元素

#### 33.3 架构分析

架构分析(architectural analysis)是在功能性的需求的语境中,识别和处理系统非功能性需求(例如安全需求)的活动。其包括识别变化点和最具可能性的进化点

在UP中,架构分析既包括架构调查(识别)也包括架构设计(解决)

#### 33.4 架构分析的常用步骤

1. 识别和分析对架构有影响的非功能性需求(跟具有可变性的功能性需求也有关系,不过这里应该对非功能性需求给予非常彻底的关注),这些被称作架构因素
    - 这一步可以看做常规的需求分析
    - 就UP而言,在初始阶段,需要在补充性规格说明或者用例中粗略地记录和识别部分此类需求。在细化阶段早期进行的架构分析过程中,需要更仔细地对这些需求进行调查 
2. 对于这些在架构方面具有重要影响的需求,需要分析可供选择的办法并创建解决这些影响的解决方案,也就是架构决策
    - 决策的范围包括删除需求、定制解决方案、终止项目、聘用一个专家等

#### 33.5 科学:架构因素的识别和分析

**架构因素**

所有的FURPS+需求对系统的架构都具有重要影响,其中涉及可靠性、进度安排、技巧和成本约束等。例如:如果工期紧、预算少且技术生疏,则选择购买或者外包会比自己构建所有构件更加明智

无论如何,对架构最具有影响的重要因素可以包括于FURPS+分类中:功能性、可靠性、性能、可支持性、实现和接口等。有趣的是,赋予特定架构**独一无二**的特征的,通常是非功能质量属性(例如可靠性或性能),而不是其功能需求

在UP中,这些具有架构已有的因素称为关键架构需求

**质量场景**

在架构因素分析中定义质量需求时,推荐使用“质量场景”,因为它定义了可度量的(至少可观察的)响应,并因此能够加以验证。诸如“系统易于修改”这样含糊描述,很难具有实用性

质量场景鼓励使用可度量的陈述记录所有(至少大部分)因素,形如<刺激><可度量响应>的简短陈述。比如:客服报考一个bug时,应在一个工作日内电话回复

**描述架构因素**

架构分析的一个重要目的是理解架构性因素的影响、优先级和可变性(立即需要的灵活性和未来的演化)。建议创建包含以下信息的表(因素表):

因素、度量和质量场景、可变性(当前的灵活性和未来的演化性)、该因素对涉众、架构以及其他因素的影响、对于成功的优先级、困难或风险

#### 33.7 艺术:架构性因素的解决

**记录架构选择、决策以及动机**

建议保存与重要问题和决定有关的信息(比如可供选择的方案、决策、影响因素和动机等),这些被称作技术备忘录、问题卡、架构途径文档。

**引导结构决策的目标**

1. 强制性约束,包括强制性的安全和法律规定
2. 业务目标
3. 所有其他目标

**优先级和进化点:工程化不足和过度工程化**

架构决策的另一个重要特征是按进化点可能发生的概率区分优先级

决定在何处花费精力进行必要的设计,预防将来可能的变化,这是架构设计师的艺术

**基本的架构设计原则**

- 低耦合
- 高内聚
- 防止变异(接口、间接性、服务查找等)

**关注分离以及局部化影响**

架构分析时,关注分离(separation of concern)是另外一个基本原则。这一原则也可以应用于小尺度的对象,但在架构分析中效果最明显

横切面关注(cross-cutting concern)是指在系统中具有广泛应用或影响的事物,例如,数据持久化、安全等。

关注分离的设计方案将持久化支持和安全性支持分离到单独的“事物”中。业务类中仅有业务逻辑,而没有持久化和安全逻辑。同样,持久化子系统只关注持久化,不关注安全;安全子系统同样不关注持久化

关注分离是在架构级别上考虑低耦合、高内聚目标的大尺度方式。此原则也适用于小尺度对象,因为如果不遵循该原则,将会导致类具有多个职责范围,降低了内聚性

**实现关注分离的几个大尺度的技巧**

1. 将有关事物模块化,封装到单独的构件中,并且调用其服务
2. 使用装饰者
3. 使用后编译器和面向方面技术

#### 33.9 过程:UP中的迭代架构

UP是以架构为中心的迭代和进化式方法。

架构分析活动从初始阶段就开始进行,它是细化阶段关注的重点。架构分析时软件开发中具有高优先级、影响深远的活动

**UP制品中的架构信息**

- 架构性因素被记录在补充规格说明中
- 架构性决策被尽量在SAD中。这其中包含技术备忘录和架构视图的描述

**阶段**

- 初始阶段——如果不能确定技术上是否满足关键的架构性需求,开发团队可以实现一个架构概念验证原型来确定其可行性
- 细化阶段——细化阶段的主要目标时实现核心的风险架构元素,因而,大部分的架构分析都在细化阶段完成。正常情况下,细化阶段完成时,因素表、技术备忘录和SAD的大部分内容都已经完成
- 移交阶段——尽管在理想情况下,架构性因素和决策在移交阶段之前都被解决,但本阶段结束时人可能需要修订SAD以便确保与最终部署的系统一致
- 后续进化循环——设计新版本前,通常会重温架构性因素和决策

### 第34章 逻辑架构的精化

#### 34.2 使用层模式的协作

在架构层次上有两个重要的设计决策:
1. 有哪些大尺度分块
2. 它们是如何连接的?

架构性的层模式用来指导定义大尺度的分块,同时诸如外观、控制器和观察者这一的微观架构设计模式则可以用来设计层和包之间的连接。

**外观**

对于表示子系统的包,GoF外观模式是最常见的访问模式

外观一般不应该暴露太多底层操作,相反,它只应该暴露少数高层操作——粗粒度服务

通常,外观不会直接执行任务,而是由隐藏在外观下的子系统对象来完成工作,外观是这些对象的统一或中介

#### 34.3 有关层模式的其他问题

**层的障碍和禁忌**

- 在某些情形,增加层将导致性能问题。例如,在高性能的图形游戏中,在直接访问显卡之上添加抽象层会导致性能问题
- 层模式是少数几个核心架构模式之一,但不是对所有问题都适用。有些情况可以使用管道和过滤器模式会更好

#### 34.4 模型-视图分离和“向上”通信

窗口如何得到需要显示的消息?

1. 观察者模式,使GUI对象简单地作为实现了诸如PropertyListener这样的接口的对象
2. UI外观对象。在UI层增加接收来自底层请求的外观

### 第35章 包的设计

#### 35.1 组织包结构的准则

准则:包在水平和垂直划分上的功能性内聚

**RC = 内部关系的数量/类型的数量**

内部关系的数量包含属性和参数关系、继承以及包内类型之间的接口实现。

RC越大表明包的内聚性越强

准则:将一组功能上相关的接口放入单独的包,与其实现类分离。

准则:用于正式工作的包和用于聚集不稳定类的包:减少对不稳定包的广泛依赖

准则:职责越多的包越需要稳定

**增强包稳定性的方法**

- 包中仅包含或者主要包含接口和抽象类
- 不依赖于其他的包,或者仅依赖非常稳定的包,或者封装了依赖关系以使其不受影响

准则:将不相关的类型分离出去

准则:使用工厂模式减少对具体包的依赖

准则:包之间没有循环依赖

**解决循环依赖**

两个解决方案:

1. 将参与循环的类型分解出来形成较小的新包
2. 使用接口来打破循环

使用接口打破循环的步骤:

1. 重新定义一个在包中被依赖的类,使其实现新的接口
2. 在一个新包中定义新的接口
3. 重新定义依赖于原来类的类型,使其依赖于新包的接口,而不是原来的类
 

### 第36章 使用GoF模式完成更多对象设计

#### 36.3 处理故障

异常最适合于处理资源(例如硬盘、内存、网络和访问数据库和其他外部服务)故障的情形

怎样来调用异常?给一个异常命名,这个名字要能够描述这个异常为什么被抛出,而不是要描述抛出者。

**异常的处理**

- 集中错误日志
- 错误会话

#### 36.7 对一组相关的对象使用抽象工厂模式

**如何创建实现相同接口的一组相关的类?**

定义一个工厂接口(抽象工厂)。为每一组要创建的事物定义一个具体工厂类。也可以定义实际的抽象类来实现工厂接口,并且为扩展该抽奖类的具体工厂提供公共服务

### 第37章 使用模式设计持久性框架

#### 37.16 事务状态和状态模式

问题:对象的行为依赖于它的状态,而它的方法中包含能够反映依赖状态的条件动作的case逻辑,是否存在替代条件逻辑的方法?

方案:给每个状态创建状态类,并实现一个公共的接口。将语境对象中的依赖于状态的操作委派给其当前的状态对象。确保语境对象总是指向反映其当前状态的状态对象

#### 37.17 使用命令模式设计事务

问题:如何处理诸如排序、排队、延迟、记录日志或重做等功能的请求或任务?

方案:为每个任务创建一个类,并实现共同的接口

### 第38章 UML部署图和构件图

部署图表示的是如何将具体软件制品分配到计算节点上。部署图表示了软件元素在物理架构上的部署,以及物理元素之间的通信

### 第39章 结构的文档化:UML和N+1视图模型

#### 39.1 SAD和架构视图

软件架构文档SAD描述了有关架构的总体思想,包含了架构分析的关键决策。能够帮助开发人员理解系统的基本概念

**架构视图**

RUP的定义是:从指定视角出发的系统架构视图;其主要关注结构、模块化、基本构件和主要控制流等方面。这个定义缺少一个重要方面:动机。架构视图是从某个角度观察系统的窗口,只强调关键信息或想法,忽略其他

**架构视图的创建**

- 系统创建之后,作为总结和面向未来开发者的学习辅助材料
- 在某个迭代里程碑之后(比如细化阶段结束之后)进行创建,作为当前开发团队和新成员的学习辅助材料
- 在早期迭代阶段,预测地创建架构视图,这样能够对创造性的设计工作产生帮助。但是要承认,随着设计和实现工作的进展,该视图会不断演化

**N+1视图模型**

反映系统不同侧面,也被称作4+1,其中4是指:逻辑视图、进程视图、部署视图、数据视图,+1是指用例视图

准则:每个视图不仅包含图,还有解释和澄清的文字,讨论动机的文字分层重要

##六、其他主题

### 第40章 迭代式开发和敏捷项目管理的进一步讨论

#### 40.1 如何计划一次迭代

1. 确定迭代的时间长度,通常为2-6周
2. 召集迭代计划会议
3. 列出本次迭代的潜在目标,并标记优先级
4. 团队每个成员应为本次迭代编制个人资源预算(时间)
5. 对某一目标,在计划中对其进行较为详细的描述,并分解其问题,进行讨论,并形成粗略估计
6. 反复进行第5步指导确定了足够多的工作:迭代阶段的总任务应该与总的资源预算相匹配