敏捷软件开发:原则、模式与实践——第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 ...
随机推荐
- linux oracle服务器无密码登录dba
1.su - oracle 切换到oracle 2.sqlplus sys/manger as sysdba 3.新建用户: create user username identified by pa ...
- Python实践练习:多重剪贴板
题目 假定你有一个无聊的任务,要填充一个网页或软件中的许多表格,其中包含一些文本字段.剪贴板让你不必一次又一次输入同样的文本,但剪贴板上一次只有一个内容.如果你有几段不同的文本需要拷贝粘贴,就不得不一 ...
- mongodb主从复制 副本集(六)
主从复制副本集 8888.conf dbpath = D:\software\MongoDBDATA\07\8888 #主数据库地址port = 8888 #主数据库端口号bind_ip = 127. ...
- 「小程序JAVA实战」小程序注册界面的开发(29)
转自:https://idig8.com/2018/08/27/xiaochengxujavashizhanxiaochengxuzhucejiemiandekaifa29/ 小程序基本所有的常用组件 ...
- Linux下network提示Determining if ip address
转自:https://blog.csdn.net/ranran0224/article/details/73323925 Centos系统重启网络服务network 会提示Determining if ...
- docker redis4.0 集群(cluster)搭建
前言 redis集群对于很多人来说非常熟悉,在前些日子,我也有一位大兄弟也发布过一篇关于在阿里云(centOS7)上搭建redis 集群的文章,虽然集群搭建的文章在网上很多,我比较喜欢这篇文章的地方是 ...
- WOW研究资料收集
1,模拟服务器:trinity core, sunwell core等 参考:逍遥魔兽 2,大芒果:通用网游框架,带了WOW的模拟模块 参考资料: 大芒果论坛http://www.mangoscn.c ...
- IPHONE 64位和32位
参考段一:iPhone 5没有64位的,只有32位架构,苹果是从iPhone 5s开始对全线移动产品使用64位架构.iPhone 5s发布之后的所有产品都是64位的使用LUAJIT或LUAC都可以对L ...
- cmder 设置
添加到系统变量 windows10可直接使用小娜搜索环境变量,然后将Cmder.exe所在目录加入Path项即可.之后通过win+r输入cmder即可启动 添加到右键菜单 在管理员权限的命令窗口下(可 ...
- js 操作数组的一些方法
1.从数组中获取最大的数 function getMaxfromarr(arr) { var lasti = 0; for (var i = 0; i < arr.length; i++) { ...