前言
程序员在软件开发中, 不可避免地要绘图, 例如, 经常可以看到软件系统, 会绘制软件架构图.
然而, 在传统软件工程领域, 其实是没有软件架构图的!
传统的软件工程领域, 一般有2种方式来分析设计:
- 结构化方式(Structure Analysis,SA)
- 面向对象方式(Object-Oriented Method,OOA)
有的图难以匹配规范, 在传统软件工程中, 就划分为示意图.
不过, 大佬们在传统软件工程领域范围外, 也制定了C4图等新的软件图规范.
下面系统化整理常用的绘图.
一、需求分析阶段
1.结构化分析方法
结构化分析方法的关注点是: 信息的流动,
它认为一切信息系统都是由信息流构成的, 信息流有起点(数据源), 有终点(数据潭), 有中间的加工.
需求分析阶段使用: 数据流图(Data Flow Diagram)
1.1 DFD数据流图
DFD用于描述数据变化, 是结构化方式的核心图.
基本符号有4种, 如下:
数据流表示了数据的流动.
加工表示了对数据的变换处理.
数据存储表示了数据的静态存储.
数据源表示了数据的起点, 数据潭表示了数据的终点.
示例:
第一级的DFD称为0层DFD,
继续分解, 得到1层DFD,
同时还要提供数据字典(数据字典是对数据概念的解释)。
完整示例:
0层DFD:
1层DFD:
数据字典如下,“{}”表示多个,“|”表示或者:
存折=户名+所号+帐号+开户日+性质+(印密)+1{存取行}50
户名=2{字母}24
所号=“001”…“999” 注:储蓄所编码,规定三位数字
帐号=“00000001”…“99999999” 注:帐号规定由八位数字组成
开户日=年+月+日
性质=“1”…“6” 注:“1“表示普通用户,“5”表示工资户等
印密=“0”
存取行=日期+(摘要)+支出+存入+余额+操作+复核
日期=年+月+日
年=“0000”…“9999”
月=“01”…“12”
日=“01“…“31”
摘要=1{字母}4 注:表明是存还是取
支出=金额
存入=金额
金额=0.01…999999.99
操作=“00001”…“99999” 注:操作、复核是银行职员代码
复合=“00001”…“99999”
2.面向对象分析方法
UML是面向对象方式的经典模型表达工具.
UML图分为静态的和动态的,
静态图, 表达了结构, 有: 类图, 构件图, 部署图, 对象图, 包图, 组合结构图
动态图, 表达了行为, 有: 用况图, 活动图, 状态图, 顺序图, 通信图, 交互概观图, 定时图
本文只介绍实际常用的几个.
2.1 UML-类图
类图(Class diagram)是可视化地表达系统静态结构模型的工具, 包含类、接口、关联、泛化和依赖等关系。
类图是面向对象方式的核心图.
例如,在设计模式中,类图是常见的表达方式。
如上图所示,
第一行是类名,
第二行是类中的属性,
第三行是类中的方法。
属性和方法前面的+和-表示了可见性:
+表示是public共有
-表示是private私有
#表示是受保护的,只有子类才可访问
~表示是包内的,同一包下才可访问
类之间常见的是以下6种关系, 各种关系的强弱顺序:
泛化=实现> 组合> 聚合> 关联> 依赖
-
泛化(generalization)
泛化可理解为继承, 示例:
-
实现(realization)
常见的是接口的实现, 示例:
-
组合(composition)
组合是紧密聚合, 表达了整体/部分的关系, 但是部分不可脱离整体而单独存在. 示例:
嘴组合于头, 不能没有头的概念而单独存在, 部分指向整体. -
聚合(aggregation)
聚合是松散聚合, 表达了整体/部分的关系, 但是部分可脱离整体而单独存在. 示例:
书聚合于图书馆, 书能单独存在, 部分指向整体. -
关联(association)
关联表示了拥有的关系,如果A指向B, 说明A类中有B类的成员变量.
可以有箭头(表示单向关联), 也可以无箭头(表示双向关联), 示例:
- 依赖(dependency)
依赖表示了使用的关系, 如果A指向B, 说明A在局部使用了B,
一般是局部变量、方法参数和静态方法这样的局部引用。示例:
2.2 UML-状态图
状态图虽然是面向对象方式的, 但是结构化方式一般也会使用它.
状态图是显示一个状态机的图, 强调了从一个状态到另一状态的控制流.
示例:
2.3 UML-用况图
用况图(use case diagram), 有时也被称为用例图, 是一种表达系统功能模型的图形化工具.
用况图是各个开发阶段都使用的UML图形.
用况图包含6个元素:
1.主题(subject)
主题是由一组用况锁描述的一个类, 通常是一个系统或者子系统, 示例:
2.用况(use cases)
用况表达了参与者(actor)使用系统的一组动作序列, 描述了系统功能行为, 是集成测试和系统测试的依据.
和结构化方式中的"加工"不同, 加工关注的是数据流, 用况关注的是参与者的交互.
用况示例:
3.参与者(actor)
参与者表达了一组高内聚的角色, 一般就是系统用户, 示例:
4.关联(association)
在用况图中, 关联是一种参与关系, 用于连接参与者和用况, 表达了参与者参与一个用况, 示例:
5.泛化(generalization)
在用况图中, 用况之间有三种关系: 泛化, 扩展, 包含.
泛化类似于继承, 例如, 个人客户和企业客户泛化于客户, 示例:
6.依赖(dependency)
在用况图中, 用况之间有三种关系: 泛化, 扩展, 包含.
扩展(extend)和包含(include), 属于依赖的变体, 实际业务很少见人用, 示例:
销售人员订货这个用况, 包含了"提供顾客数据"这个用况的行为,
索取货物目录, 有个扩展场景, 就是销售人员订货时来索取
2.4 UML-时序图
时序图(Sequence Diagram), 也被称为顺序图, 是一种交互图,
由一组对象以及按照时间顺序组织的对象直接的关系组成, 其中还包含对象之间发送的消息.
对象A调用对象B,
同步调用, 使用实心三角箭头,
返回数据, 使用枝形箭头+虚线,
异步调用, 使用枝形箭头.
注意, DFD中的箭头线表达的是数据流动方向, 时序图中表达的是调用方向, 绘画时容易混淆.
时序图中还有操作子的概念, 用来表达循环、条件、并发执行等控制,
但是实际很少见到, 许多人也看不懂, 感兴趣自己看吧.
3.其他方法
3.1 思维导图
思维导图是表达发散性思维的有效图形思维工具, 用一个中央关键词或想法以辐射线形连接所有的代表字词、想法、任务或其它关联项目的图解方式.
3.2 泳道图
参照百度经验, 泳道图(Swimlane Diagram),也叫跨职能流程图。旨在分析和展示各个部门在同一任务流程上的不同进程,明确流程环节所属的阶段、流程环节负责人、组织机构或部门。泳道图的名称由来,是流程图中对职能部门的划分像游泳池泳道相类似比拟而来。
3.3 IT界常用-原型图
原型图是产品的可视化展示图,
传统的软件工程图中, 专注于软件的本质, 重意不重形, 而原型图对于UI交互的直观表达, 弥补了这个缺陷.
它展示了看得见的界面和交互, 对于看不见的逻辑, 要以文字等形式来表达.
例如, processOn中的登录/注册原型图.
3.4 数据库ER图
E-R图(Entity Relationship Diagram),提供了表示实体类型、属性和联系的方法,用来描述现实世界的概念模型。
它也是结构化方式常用的图, 面向对象也可以使用它.
本文特指数据库的ER图, 因为一般只有数据库用ER图.
数据库ER图中有3个关系:
1对1(1:1)
1对多(1:N)
多对多(M:N)
实体的表示:方形
属性的表示:椭圆
联系的表示:菱形
示例:
二、总体设计阶段
1.结构化设计
在总体设计中, 结构化设计方法引入了2个术语: 模块和模块调用.
绘图有多种, 例如: 层次图, HIPO图等,
由于需求阶段采用的是数据流图(DFD),
因此结构化设计的思路是, 自顶向下, 功能分解, 把DFD转化为结构图, 即:
总体设计阶段使用: 模块结构图(Module Structure Diagram)和层次图(也被称为软件结构图)
2种图的区别:
模块结构图: 关心模块间的关系
层次图: 不关心模块间的关系
1.1 MSD模块结构图
模块结构图是针对DFD的细化, 尤其是针对加工的细化,
和DFD类似, 箭头表示了数据的流向,
顶层是模块,
下一层从左到右, 分别是"输入", “变换数据”, “输出”, 示例:
在初始的模块结构图后, 可以对"变换数据"(即c变换成d)部分, 继续模块分解, 示例:
1.2 层次图(软件结构图)
层次图主要用于描绘软件的层次结构。总体设计常用的是它。
用方框代表模块功能,连线表示模块功能间的调用关系。
示例:
2.面向对象设计
2.1 UML-类图
参照需求分析阶段, 是各个阶段图的细化
2.2 UML-状态图
参照需求分析阶段, 是各个阶段图的细化
2.3 UML-时序图
参照需求分析阶段, 是各个阶段图的细化
2.4 UML-用况图
参照需求分析阶段, 是各个阶段图的细化
3.其他总体设计
3.1 个人推荐-C4图
C4模型是个理解门槛很低的可视化架构设计模型, 对软件从业者很简洁友好, 这也是我个人推荐的主要理由.
C4是指System Context(系统上下文), Container(容器), Component(组件), Code(代码).
假设从从高空俯瞰软件系统, 系统会从System Context逐渐细化到Code.
外部系统使用灰色背景, 系统本身使用蓝色背景.
注意, C4图中的箭头, 一般表示的是调用, 而不是数据流向
-
System Context(系统上下文)
描述角色和各个系统的关系.
-
Container(容器)
系统由多个容器组成, 一个容器可以理解为一个进程.
-
Component(组件)
容器由组件构成, 有工具组件, 共享组件等.
-
Code(代码)
代码层面, 遵守的是UML, 参照"2.1 UML-类图"
三、详细设计阶段
1.结构化设计
详细设计阶段有多种图, 例如: 程序流程图, 盒图(N-S图), PAD图等, 实际很少见到用盒图和PAD图的.
详细设计阶段使用: 程序流程图
1.1 程序流程图
程序流程图是一种历史悠久且使用广泛的工具, 主要优点是对控制流程的描绘很直观, 便于初学者掌握.
有多直观呢, 掌握以下3个图形, 一般就够用了:
示例:
2.面向对象设计
2.1 UML-类图
参照需求分析阶段, 是各个阶段图的细化
2.2 UML-状态图
参照需求分析阶段, 是各个阶段图的细化
2.3 UML-时序图
参照需求分析阶段, 是各个阶段图的细化
2.4 UML-用况图
参照需求分析阶段, 是各个阶段图的细化
3.其他详细设计
无
总结
结构化和面向对象的区别:
结构化:任何模块都可以控制数据,随着软件规模增大,软件复杂度难以控制,偏向于函数式编程的思想
面向对象:用对象控制数据,最终控制软件复杂度
1. 结构化开发流程的各个阶段图
需求分析:
功能模型 结构化方式的核心-DFD (0层和1层等+数据字典)
数据模型-ER图
行为模型-推荐使用UML状态图
总体设计:
层次图(不关心模块间的关系,即软件结构图,常用它)
模块结构图(关心模块间的关系)
详细设计:
程序流程图
2. 面向对象开发流程的各个阶段图
需求分析:
功能模型-用例图
数据模型 面向对象方式的核心-类图
行为模型-时序图
总体设计:
UML的总体设计,是对类图等图的不断细化
详细设计:
UML的详细设计,是对类图等图的不断细化