需求分析设计之七武器

1. 概述

软件建模与设计过程可拆分为需求分析、概要设计和详细设计三个阶段。我们往往需要在不同阶段输出不同的设计文档。这个过程,除了自身的业务理解能力外,建模工具UML必不可少,其中常用的有七种(“七武器”):类图、用例图、时序图、活动图、状态图、组件图和部署图。

适用阶段 模型图 说明
需求分析:
类图 关注领域对象识别及其关系
活动图 描述业务流程
用例图 通过反映用户和软件系统的交互来描述系统的功能需求
时序图 通常用于表示对象之间的交互’这个对象可以是类对象,也可以是更大粒度的参与者’如组件、服务器、子系统等
状态图 描述状态变迁的逻辑关系
概要设计:
活动图 描述子系统和组件的交互
时序图 通常用于表示对象之间的交互’这个对象可以是类对象,也可以是更大粒度的参与者’如组件、服务器、子系统等
组件图 粒度比较粗,通常用以描述和设计软件的模块及其之间的关系,需要在设计早期阶段画出来
部署图 是整个软件设计模型中比较宏观的一种图,是在设计早期就需要画的一种模型图;还可以估算服务器和第三方软件的采购成本
详细设计:
类图 开发工程师按照类图实现代码即可
状态图 这个时候状态要用枚举值表示,以指导具体的开发
时序图 常用于描述系统内部详细的接口调用时序或业务模块数据流转过程
活动图 可用于描述一个类方法内部的计算流程

2. 工具选型

2.1. UML工具

绘图工具总体分为两类,一类是可视化工具,一类是文本化最终编译为图片,以下是我用过的工具对比。

名称 类型 优点 缺点
Visio 可视化工具 功能齐全,有模板 连接线对于手残党不友好
Visual Paradigm 可视化工具 功能齐全,有模板,专业,号称能用最新少鼠标点击完成画图操作,默认风格优美 最新版非免费
processon 可视化工具 功能齐全,有模板,能多人在线协作,有APP版本 非免费,网页体验不好
PlantUML 文本化工具 支持的模型图功能齐全,免费,手残党福音,相比拖拽绘图工具更利于专注业务建模,gitlab上提交的markdown文件可直接渲染出图片 依赖Graphviz,默认样式丑
mermaid 文本化工具 免费,很多markdown编辑器默认支持,默认样式优美,手残党福音,相比拖拽绘图工具更利于专注业务建模 支持的模型图较少

最后,个人选择plantUML,它支持常用的七种UML图,通过定制样式也可以很优美,当然,最重要的是不用耗费部分精力在画图这个事情上。
PlantUML语法说明详见>>

2.2. 设计编写工具

2.2.1. 功能诉求

  1. 支持markdown。
  2. 支持markdown中渲染预览plantUML。
  3. 支持导出成HTML、PDF格式。
  4. 支持粘贴保存截图。

2.2.2. 工具选择

名称 类型 说明
Visual Studio Code 文本编辑器 独立安装,功能繁多,忽略介绍
Markdown Preview Enhanced vsCode 插件 支持markdown预览、支持plantUML渲染、支持导出HTML和PDF、支持快速生成目录
Markdown-index vsCode 插件 自动根据markdown标题生成或更新顺序数字
Paste Image vsCode 插件 支持粘贴保存图片并转为markdown图片语法
Graphviz 图渲染工具 需要单独下载安装(否则markdown preview enhanced中的plantuml无法渲染),并配置好环境变量GRAPHVIZ_DOT,取值如:D:\Software\Graphviz\bin\dot.exe

3. “七武器”使用示例

以常见的电商下单支付场景为例,画出需求分析、设计过程中涉及的七种UML图。
使用PlantUML语法做出参考模板,并进行一定程度的美化(仿Visual Paradigm默认样式)。

3.1. 类图

刻画需求分析阶段的领域模型或者详细设计阶段的类图。

3.1.1. 对象图刻画领域模型

@startuml

' ========调整样式=============
skinparam object {
    BackgroundColor #70CFF5
    BorderColor #black
    ArrowColor #black
}

' ========停止属性的可访问性样式=============
skinparam classAttributeIconSize 0


' ========定义模型=============
object 订单{
    - 单号
    - 订单状态
    - 金额
}

object 订单明细 {
    - 商品
    - 价格
    - 数量
    - 金额
}

object 售后单{
    - 类型
    - 单号
    - 状态
}


' ========定义关系=============
订单 "1"*-right-"n" 订单明细
订单 "1" o-down-"n" 售后单
@enduml
image.png

3.1.2. 类图刻画代码模型

@startuml

' ========调整样式=============
skinparam class {
    BackgroundColor #70CFF5
    BorderColor #black
    ArrowColor #black
}
skinparam object {
    BackgroundColor #70CFF5
    BorderColor #black
    ArrowColor #black
}


' ========定义模型=============

enum 订单状态{
    待付款
    待发货(已付款)
    已发货
    交易完成(已确认收货)
    售后中
    交易关闭
    已取消
}


class 订单{
    - 单号 : string
    - 订单状态 : enum
    - 金额 : double

    + 创建()
    + 支付()
    + 发货()
    + 确认收货()
}

class 订单明细 {
    - 商品代码 : string
    - 商品名称 : string
    - 价格 : double
    - 数量 : double
    - 金额 : double
}

class 售后单{
    - 类型 : enum
    - 单号 : string
    - 状态 : enum
}

class 售后单明细{

}


' ========定义关系=============
订单 "1"*-right-"n" 订单明细
订单 "1" o-down-"n" 售后单
售后单 "1"*-right-"n" 售后单明细
@enduml

image.png

3.2. 活动图

使用活动图刻画订单业务流程。

@startuml
' ========调整样式=============
' 单个状态定义示例:state 未提交 #70CFF5 ##Black

skinparam activity {
    BackgroundColor #70CFF5
    BorderColor #black
    ArrowColor #black
}

skinparam activityDiamond {
    BackgroundColor #70CFF5
    BorderColor #black
}


' ========定义流程=============

|用户|
start
:筛选商品;
split 
    :添加购物车;
    :进入购物车;
    :购物车结算;
split again
    :立即结算;
end split

:下单支付;
if (超时未支付) then (是)
    :系统取消订单;
    note right
        订单状态:已取消
    end note
    stop
else (否)
    repeat
        :选择付款方式;
        :确认支付;
    repeat while(支付失败)
  
endif
:支付成功;
note left
订单状态:待发货
end note


|商家|
switch (商品库存)
    case (没货)
    :联系用户取消订单;
    : 取消订单;
    stop
    case (部分缺货)
    :缺货部分补发;
    case (库存充足)
    :备货;
endswitch
:物流交接;
:通知发货;  


|物流|
:运输;
:配送;

|用户|
:确认收货;
stop
@enduml

image.png

3.3. 状态图

@startuml
' ========调整样式=============
' 单个状态定义示例:state 未提交 #70CFF5 ##Black

skinparam state {
    BackgroundColor #70CFF5
    BorderColor #black
    ArrowColor #black
}

'连线样式:默认弯曲、ortho-折线、polyline-斜线
'skinparam linetype polyline

' ========定义流程=============

[*] -right-> 待付款 :下单
待付款 : initial
待付款 -right-> 待发货 : 支付
待发货 : paid
待发货 -right-> 已发货 : 商家发货
已发货 : shipped
已发货 -right-> 交易完成 : 已收货
交易完成 : received
待付款 -down-> 已取消 : 超时未支付
已取消 : canceled
待发货 -down-> 已取消 : 商家无货
交易完成 --> 售后中: 退/补/换货
售后中 : applying
售后中 -right-> 交易关闭 : 完成退款
交易关闭 : closed
交易关闭 -> [*]
已取消 --> [*]
@enduml

image.png

3.4. 时序图

以支付接口交互为例
箭头规则参照Visual Paradigam:同步调用=实线+实心粗箭头;返回值=虚线+细箭头;异步调用=实线+细箭头。

@startuml

' ========调整样式=============
' 单个状态定义示例:state 未提交 #70CFF5 ##Black

skinparam sequence {
ArrowColor red

LifeLineBorderColor blue
LifeLineBackgroundColor #A9DCDF

ParticipantBorderColor #black
ParticipantBackgroundColor  #70CFF5
}
' ========定义流程=============

APP -> APP : 筛选并下单
activate APP
deactivate APP

autonumber 1
activate 订单服务
APP -> 订单服务 : 调用准备支付接口    
activate APP
alt 首次调用
    autonumber "<b>'1.1.'0"    
        订单服务 -> 订单服务 : 支付申请单 [类型-付款,状态-处理中]
        订单服务 -->> APP : 返回业务的支付信息  
    
else 二次调用
    autonumber "<b>'1.2.1.'0"
    alt 支付申请单[处理中]
        订单服务 -->> APP : 直接返回业务的支付信息  
    else 支付申请单[处理失败]
    autonumber "<b>'1.2.2.'0"
        订单服务 -> 订单服务 :更新交易凭证号,且置支付申请单 [状态-处理中]
        订单服务 -->> APP : 返回业务的支付信息  
    end
    
end
deactivate APP
deactivate 订单服务


autonumber 2
APP -> 第三方支付平台 : 调用支付前提交接口
activate 第三方支付平台
activate APP
alt 网络异常
    autonumber "<b>'2.1.'0"
    第三方支付平台 -->> APP : 网络异常,**转步骤2**
else 调用失败
    autonumber "<b>'2.2.'0"
    第三方支付平台 -->> APP : 返回失败信息
    activate APP
        APP -> 订单服务 : 调用记录失败结果接口
        activate 订单服务
        订单服务 -> 订单服务 : 支付申请单 [状态-处理失败]                
        订单服务-->> APP : 明确返回记录成功,**转步骤2**(失败需要重试)
        deactivate 订单服务
    deactivate APP
else 调用成功
    autonumber "<b>'2.3.'0"
    第三方支付平台 -->> APP : 返回提交成功结果,**转步骤3**
end
deactivate APP
deactivate 第三方支付平台


autonumber 3.1
APP -> 第三方支付平台 : 调用确认支付接口    
activate 第三方支付平台 
activate APP            
        alt 网络异常
            autonumber "<b>'3.1.1.'0"
            第三方支付平台 -->> APP : 网络异常,**转步骤3.1**,进行重试
        else 调用失败
            autonumber "<b>'3.1.2.'0"
            第三方支付平台 -->> APP : 返回失败信息,**转步骤2.2.1**,记录失败结果

        else 调用成功
            autonumber "<b>'3.1.3.'0"                                
            第三方支付平台 -->> APP : 返回完成支付信息,**转步骤3.2**,记录成功结果

            
            APP -> 订单服务 : 调用确认完成支付
            activate 订单服务
            订单服务 -> 订单服务 : 置支付申请单位已完成,\n订单状态为待发货 
            订单服务 -->> APP : 返回订单完成支付信息
            deactivate 订单服务
        end

deactivate APP
deactivate 第三方支付平台 

@enduml
image.png

3.5. 组件图

@startuml
' ========调整样式=============
' 单个状态定义示例:state 未提交 #70CFF5 ##Black

skinparam interface {
    BackgroundColor #70CFF5
    BorderColor #black
}


skinparam component {
  FontSize 13
  BackgroundColor #70CFF5
  FontName Courier
  BorderColor black
  ArrowFontName Impact
  ArrowColor #black
  ArrowFontColor #777777
}



' ========定义内容=============
component [订单] as order
component [商品] as goods
component [支付申请单] as pay
component [库存] as inv
component [售后单] as rtn
component [促销] as prom

order ..> goods
order ..> prom
prom ..> goods
order ..> pay
order ..> inv
rtn ..> order
@enduml
image.png

3.6. 部署图

@startuml
' ========调整样式=============
' 单个状态定义示例:state 未提交 #70CFF5 ##Black

skinparam usecase {
    BackgroundColor #70CFF5
    BorderColor #black
    ArrowColor #black
}

skinparam actor {
    BackgroundColor #70CFF5
    BorderColor #black
}

skinparam component {
  BackgroundColor #70CFF5
  BorderColor black
  ArrowColor #black
  ArrowFontColor #777777
}

skinparam cloud {
  BackgroundColor #70CFF5
  BorderColor black
  ArrowColor #black
  ArrowFontColor #777777
}

skinparam database {
  BackgroundColor #70CFF5
  BorderColor black
  ArrowColor #black
  ArrowFontColor #777777
}

skinparam rectangle{
    roundCorner 25 ' 设置圆角
}

' ========定义内容=============

 
rectangle 前台 as userNode #line.dashed;{
    component "APP" as app
    component "小程序" as miniApp
    '通过hidden控制水平布局
    app -[hidden]left- miniApp 
    component "web端" as pcWeb
    miniApp -[hidden]right- pcWeb
   
}


rectangle 中台 #line.dashed;{
    cloud 阿里云SLB as slb

    node 中台网关云服务器 as gatewayNode{
        component [api-gateweay] as gateway <<API服务网关>>
    }

    node 订单云服务器 as orderNode{
    component [order-web] as orderWeb <<订单Web服务>>
    component [order-service] as order <<订单中台服务>>
    }

    node 库存云服务器 as invNode{
    component [inv-service] as inv <<库存中台服务>>
    }

    database 订单中台云数据库 as orderDS <<MySQL>>
    database 库存中台云数据库 as invDS <<PostgreSQL>>

}

rectangle 后台 #line.dashed;{
    node ERP服务器 as erp{
    component [inv-transfer] as erpInvTransfer <<ERP库存中台交换服务>>
    component [order-transfer] as erpOrderTransfer <<ERP订单中台交换服务>>
    }

    database ERP数据库 as  erpDS <<Oracle>>
}

userNode -- slb : HTTPS
slb -- gatewayNode
gateway -->order
order -up-> orderDS
orderWeb -right-> order
gateway -->inv
inv -up-> invDS
inv ..> erpInvTransfer
order ..> erpOrderTransfer
inv -left- order
erpInvTransfer --> erpDS
erpOrderTransfer --> erpDS

@enduml
image.png

3.7. 用例图

开发阶段用的较少,PS:记箭头关联关系表示好累 _

@startuml
' ========调整样式=============
' 单个状态定义示例:state 未提交 #70CFF5 ##Black

skinparam usecase {
    BackgroundColor #70CFF5
    BorderColor #black
    ArrowColor #black
}

skinparam actor {
    BackgroundColor #70CFF5
    BorderColor #black
}


' ========定义内容=============

 
left to right direction
actor "用户" as user
usecase "网上购物" as ecBuy
usecase "下订单" as order
usecase "搜索商品" as searchGoods
usecase "添加购物车" as addBasket
usecase "支付" as pay
usecase "取消支付" as cancelPay 

' ========定义内容=============
' 箭头关系:--> 依赖, <|--泛化(继承) ,..> 包含或者扩展

user --> ecBuy
ecBuy <|-- order
order ..> searchGoods : <<包含>>
order ..> addBasket : <<包含>>
order ..> pay : <<包含>>
cancelPay ..> pay : <<扩展>>

@enduml
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,376评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,126评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,966评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,432评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,519评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,792评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,933评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,701评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,143评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,488评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,626评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,292评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,896评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,494评论 2 348

推荐阅读更多精彩内容