敏捷软件开发:原则、模式与实践——第13章 写给C#程序员的UML概述
第13章 写给C#程序员的UML概述
UML包含3类主要的图示。静态图(static diagram)描述了类、对象、数据结构以及它们之间的关系,藉此表现出了软件元素间那些不变的逻辑结构。动态图(dynamic diagram)展示了软件实体在运行过程中是如何变化的,其中描述了运行流程或者实体改变状态的方式。物理图(physical diagram)展示了软件实体不变的物理结构,其中描述了诸如源文件、库、二进制文件、数据文件等物理实体以及它们之间的关系。
查看如下代码,这段程序实现了一个基于简单二叉树算法的映射(map)数据结构,熟悉代码后,查看后面的图示:
using System;
namespace TreeMap
{
public class TreeMap
{
private TreeMapNode topNode = null;
public void Add(IComparable key, object value)
{
if (topNode == null)
topNode = new TreeMapNode(key, value);
else
topNode.Add(key, value);
}
public object Get(IComparable key)
{
return topNode == null ? null : topNode.Find(key);
}
}
internal class TreeMapNode
{
private static readonly int LESS = ;
private static readonly int GREATER = ;
private IComparable key;
private object value;
private TreeMapNode[] nodes = new TreeMapNode[];
public TreeMapNode(IComparable key, object value)
{
this.key = key;
this.value = value;
}
public object Find(IComparable key)
{
if (key.CompareTo(this.key) == ) return value;
return FindSubNodeForKey(SelectSubNode(key), key);
}
private int SelectSubNode(IComparable key)
{
return (key.CompareTo(this.key) < ) ? LESS : GREATER;
}
private object FindSubNodeForKey(int node, IComparable key)
{
return nodes[node] == null ? null : nodes[node].Find(key);
}
public void Add(IComparable key, object value)
{
if (key.CompareTo(this.key) == )
this.value = value;
else
AddSubNode(SelectSubNode(key), key, value);
}
private void AddSubNode(int node, IComparable key,
object value)
{
if (nodes[node] == null)
nodes[node] = new TreeMapNode(key, value);
else
nodes[node].Add(key, value);
}
}
}
13.1 类图
类图展示了程序中主要的类和关系。
- 矩形表示类,箭头表示关系。
- 在本图中,所有的关系都是关联(association)关系。关联是简单的数据关系,其中一个对象或者或者持有另一个对象的引用,或者调用其方法。
- 关联上的名字映射为持有该引用的变量名。
- 一般来说,和箭头相邻的数组表示该关系所包含的实例个数。如果数字比1大,就意味着某种容器,通常是数组。
- 类图标中可以分成多个格间。通常,最上面的格间存放类的名字。其他格间中描述函数和变量。
- <<interface>>符号用来说明IComparable是一个接口。
- 这里显示的大部分符号都是可选的。

13.2 对象图
它展示了在系统执行的某个特定时刻的一组对象和关系。你可以把它看做是一个内存快照。

13.3 顺序图
它描述了TreeMap的Add方法是如何实现的。

人形线条图表示了一个未知调用者。这个调用者调用了TreeMap对象的Add方法。如果topNode变量为null,TreeMap就创建一个新的TreeMapNode对象并把它赋给topNode。否则,TreeMap就向topNode发送Add消息。
方括号中的布尔表达式称为监护条件(guard)。它们指示出应该选择哪条路径。终结在TreeMapNode图标上的消息箭头表示对象构造。带有小圆圈的箭头称为数据标记(data taken)。TreeMap下面的窄矩形条称为激活(activation)。它表示Add方法执行了多少时间。
13.4 协作图
它描述了TreeMap.Add中topNode不为null的情况。协作图中包含了顺序图中所包含的同样的信息。不过,顺序图是为了清楚地表达出消息的顺序,而协作图则是为了清楚地表达出对象之间的关系。
对象被称为链(link)的关系连接起来。只要一个对象可以向另外一个对象发送消息,就存在链关系。在链上传递的正是消息本身。它们表示为小一些的箭头。消息上标记有消息名称、消息顺序号以及任何使用的监护条件。
带点的顺序号表示调用的层次结构。TreeMap.Add函数(消息1)调用TreeMapNode.Add函数(消息1.1)。因此,消息1.1是消息1所调用的函数发送的第一条消息。
13.5 状态图
UML可以非常全面地表示有限状态机。下图展示了一个地铁旋转门的状态机:

它有两个状态:Locked和Unlocked。可以向这个机器发送两个事件。coin表示向旋转门投入了一枚硬币。pass表示用户已经通过了旋转门。
图中的箭头称为迁移(transition)。其上的标记有出发迁移的事件以及该迁移执行的动作。当一个迁移被触发时,会导致系统的状态发生改变。
翻译成自然语言描述:
- 如果在Locked状态收到coin事件,就迁移到Unlocked状态并调用Unlock函数。
- 如果在Unlocked状态收到pass事件,就迁移到Locked状态并调用Lock函数。
- 如果在Unlocked状态收到coin事件,就保持在Unlocked状态并调用Thankyou函数。
- 如果在Locked状态收到pass事件,就保持在Locked状态并调用Alarm函数。
13.6 结论
本章中的图示对于大多数场合来说足够了。大部分程序员了解这么多UML知识就足以应对实际工作需要了。
摘自:《敏捷软件开发:原则、模式与实践(C#版)》Robert C.Martin Micah Martin 著
转载请注明出处:
作者:JesseLZJ
出处:http://jesselzj.cnblogs.com
敏捷软件开发:原则、模式与实践——第13章 写给C#程序员的UML概述的更多相关文章
- 敏捷软件开发 原则 模式 与实践 - OCP原则
最近在读BOB大叔的敏捷软件开发,特别是TDD那一章节,启示真的不少,从测试驱动开发,讲到驱动表明程序设计的意图,从设计意图讲到对象依赖的解耦,从解耦建立Mock对象. 其实是对每个模块都编写单元测试 ...
- 《敏捷软件开发-原则、方法与实践》-Robert C. Martin读书笔记(转)
Review of Agile Software Development: Principles, Patterns, and Practices 本书主要包含4部分内容,这些内容对于今天的软件工程师 ...
- 敏捷软件开发vs传统软件开发
摘要 本文介绍了传统软件开发(着重介绍了传统软件开发中常用的瀑布模型)和敏捷软件开发,以及敏捷开发和传统开发的对比. 一.传统软件开发 比较常用的几种传统软件开发方法:瀑布式开发.迭代式开发.螺旋开发 ...
- 敏捷软件开发_实例2<四>
敏捷软件开发_实例2 上一章中对薪水支付案例的用例和类做了详细的阐述,在本篇会介绍薪水支付案例包的划分和数据库,UI的设计. 包的划分 一个错误包的划分 为什么这个包是错误的: 如果对classifi ...
- 敏捷软件开发:原则、模式与实践——第14章 使用UML
第14章 使用UML 在探索UML的细节之前,我们应该先讲讲何时以及为何使用它.UML的误用和滥用已经对软件项目造成了太多的危害. 14.1 为什么建模 建模就是为了弄清楚某些东西是否可行.当模型比要 ...
- 敏捷软件开发:原则、模式与实践——第12章 ISP:接口隔离原则
第12章 ISP:接口隔离原则 不应该强迫客户程序依赖并未使用的方法. 这个原则用来处理“胖”接口所存在的缺点.如果类的接口不是内敛的,就表示该类具有“胖”接口.换句话说,类的“胖”接口可以分解成多组 ...
- 敏捷软件开发:原则、模式与实践——第10章 LSP:Liskov替换原则
第10章 LSP:Liskov替换原则 Liskov替换原则:子类型(subtype)必须能够替换掉它们的基类型(base type). 10.1 违反LSP的情形 10.1.1 简单例子 对L ...
- 敏捷软件开发:原则、模式与实践——第8章 SRP:单一职责原则
第8章 SRP:单一职责原则 一个类应该只有一个发生变化的原因. 8.1 定义职责 在SRP中我们把职责定义为变化的原因.如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.同时,我 ...
- 【Scrum】-NO.40.EBook.1.Scrum.1.001-【敏捷软件开发:原则、模式与实践】- Scrum
1.0.0 Summary Tittle:[Scrum]-NO.40.EBook.1.Scrum.1.001-[敏捷软件开发:原则.模式与实践]- Scrum Style:DesignPattern ...
随机推荐
- 十七.jQuery源码解析之入口方法Sizzle(1)
函数Sizzle(selector,context,results,seed)用于查找与选择器表达式selector匹配的元素集合.该函数是选择器引擎的入口. 函数Sizzle执行的6个关键步骤如下: ...
- GroupVarint
folly/GroupVarint.h folly/GroupVarint.h is an implementation of variable-length encoding for 32- and ...
- public interface Sampler extends Serializable, TestElement
在看jmeter源码时看到的,当时就傻了,不能啊,java中只能是单继承啊,呃,其实是类只能是单继承,而接口可以多继承,不要以为extends后边跟的都是类 Serializable, TestEle ...
- Monkey Test 命令使用
1. 命令使用 Monkey是一个命令列工具 ,可以运行在仿真器里或实际设备中.它向系统发送伪随机的使用者事件流,实现对正在开发的应用程序进行压力测试.Monkey包括许多选项,它们大致分为四大类: ...
- CodeSmith介绍和常见问题解决方案
一.CodeSmith介绍 CodeSmith模板代码生成实战详解 https://www.cnblogs.com/knowledgesea/p/5016077.html 二.CodeSmith连接 ...
- 1、redis安装与启动
1.安装包下载 官网上下载:http://www.redis.io/ 安装版本:3.0.7 安装环境:CentOS 下载命令:wget http://download.redis.io/release ...
- Delegate(代理)异常:该委托必须有一个目标
转自 Delegate(代理)异常:该委托必须有一个目标 在代理调用BeginInvoke(new AsyncCallback(callBack), null);时,会抛这个异常的原因是该代理变量代理 ...
- 全部物料的交期都要加上两天 V_OUT_PR
DUE_DATETIME加上两天就可以,如果只是部分物料的话,就要根据物料组或者别的一些条件去判断
- Zookeeper的基本概念和重要特性
目录 1. 什么是Zookeeper 2. Zookeeper集群角色 3. Zookeeper的数据模型 3.1 Znode的类型 3.2 Znode的结构 4. Zookeeper的事件监听机制 ...
- 使用CreateJS绘制数字盒子