正如任何生物同样,软件也有孕育,诞生,成长,成熟以及衰亡的生命过程,常称为“软件生命周期”。软件生命周期通常分为几个阶段:既制定计划、需求分析、设计、编码、测试、运行和维护。而UML则支持从需求分析到设计再到编码的过程。php
需求分析和设计占了整个软件生命周期的两个部分,可见其重要性,而不少时候,开发同窗经常会跳过这两步,直接进入编码阶段。本文主要使用PlantUML开源项目,结合一些实际项目中的需求进行分析和设计。前端
PlantUML是一种简单易懂的UML图形绘制语言,几行代码就能够绘制出各类UML图。在熟练以后,能够比通常的绘图工具高效许多。更重要的一点是便于版本管理,在不断迭代的功能需求中,能够持续维护。算法
前奏,是一个首歌的基调,必定程度上决定了整首歌的风格变化。需求分析是整个软件设计的基础。
有不少开发同窗会有疑问:需求分析是产品经理要干的事情啊?关咱们开发什么事情?其实否则,需求分析对于开发来讲,首要也是重要的目的,就是准确而且简洁的回答“谁用什么系统作什么事”。咱们一般可使用「用例图」来搞清楚这一问题。并发
例如在「晒单有礼」这个项目中,有以下用例图:app
PlantUML代码ide
@startuml工具
left to right directionoop
actor 运营人员 as D测试
actor 客户端用户 as user编码
rectangle 晒单有礼(精简版) {
D --> (晒单策略):设置
user --> (晒单)
(晒单) --> (晒单策略):匹配
}
@enduml
解析
一、@staruml 和 @enduml plantuml预发的起始和结束标识
二、left to right direction //标识图形由左向右绘制
三、actor 用户(小人图形)
四、rectangle 矩形框,内部代码图形都在这个框内
五、 --> 实线箭头
上图简单的表达了,“客户端用户使用晒单有礼系统匹配晒单策略”和“运营人员使用该系统设置晒单策略”,已经能能大概回答“谁用什么系统作什么事”了。可是还不够精细,咱们还能够作以下扩展:
上图将“晒单”和“晒单策略”进行了补充和解释。
PlantUML代码
@startuml
left to right direction
actor 运营人员 as D
actor 客户端用户 as user
rectangle 晒单有礼(扩展版) {
D --> (设置晒单策略)
(设置晒单策略) .> (设置画像):《include》
(设置晒单策略) .> (设置激励类型):《include》
user --> (查看订单列表)
(查看订单列表) --> (晒单)
(晒单) .> (发动态):《include》
(晒单) .> (匹配晒单策略):《include》
}
@enduml
解析
一、用例图除了经常使用的关联和泛化还有下面两种:
include - 一个功能能够拆分较小的部分)
extend - 一个功能的附加功能
二、(晒单) .> (发动态):《include》
表示“晒单”包含“发动态”这个动做,冒号后面其实能够是随意文本。
实际上,咱们还能够将用例图继续细化,可是并无必要这么作,用例图每每只要作到可以比较清楚的描述两个W,Who-谁来用这系统;What-用这个系统作什么。
主歌,是一首歌的中心思想,核心主题,它贯穿于整首歌当中。在概要设计中,咱们须要梳理并掌握整个项目的脉络。
有了需求分析的铺垫,咱们才能更好地进行概要设计。在上文中咱们已经提到,需求分析时,须要回答好Who&What,而概要设计则是须要概要的回答How-如何解决问题。在概要设计时,我一般会使用UML中的活动图,状态图,时序图来描述个人设计。
在UML中,活动图会比较宽泛,例如咱们常说的流程图,泳道图等均可以算是一种活动图。流程图的主要侧重点在于突出有哪些流程节点,以及节点的走向控制;泳道图则是在流程图的基础上,突出不一样角色在整个流程中的位置和做用。一般咱们会结合起来绘制。
下面咱们看一个自建圈子项目的实例:
就绘制泳道图而言,仍是推荐使用其余工具绘制。
对比一下使用其余工具绘制的图(彻底同样的流程):
PlantUML代码
@startuml
|客户端|
|H5前端|
|ServerAPI|
|CRM后台|
|客户端|
start
|ServerAPI|
if(不符合建圈要求) then
|客户端|
:不展现建圈入口;
stop
else
|客户端|
:展现建圈入口;
|H5前端|
:填写建圈表单;
|ServerAPI|
:提交表单等待审核;
|CRM后台|
if(审核不经过) then
|ServerAPI|
:私信通知不经过;
stop
else
|ServerAPI|
:私信通知经过;
|客户端|
:展现建圈任务入口;
:点击任务入口;
|H5前端|
:展现任务列表;
|ServerAPI|
if(未完成任务) then
:私信通知任务失败;
stop
else
:私信通知任务成功;
|客户端|
:保留自建圈子;
stop
@enduml
解析
一、|客户端|
双竖线表示泳道。
二、start 、stop
开始结束节点,是泳道流程图中必须的元素。
三、if ... then ... else
条件判断,通常用菱形表示。
四、通常来讲泳道中的流程只能一直往下“游”,而不能往回“游”。
状态图用来描述一个实体的各类状态,以及状态之间的转化关系。例如电商平台最多见的“订单状态”,状态繁杂多样,用状态图来表达,可让项目更加清晰。
在晒单有礼中,就有涉及到订单列表按钮状态的变换。在下面的例子中,有几个关键点:
- 必需要有起始状态和终止状态
- 状态是相对静止的
- 状态间的转化必定伴随着动做
- 状态是能够包含状态的
PlantUML代码
@startuml
[*] --> 其余订单状态变换
state 其余订单状态变换 {
[*] --> 等待付款
等待付款 --> [*] : 取消支付
等待付款 --> 等待发货 : 支付
等待发货 --> [*] : 取消订单
}
其余订单状态变换 --> 无礼确认收货 : 未命中有礼策略
其余订单状态变换 --> 有礼确认收货 : 命中有礼策略
有礼确认收货 --> 晒单 : 14天后点击确认收货
无礼确认收货 --> 晒单 : 点击确认收货
晒单 --> 查看晒单 : 发布动态
有礼确认收货 --> 晒单有礼 : 点击确认收货
晒单有礼 --> 查看晒单 : 发布动态
查看晒单 --> 有礼查看晒单 : 审核经过发送优惠券
有礼查看晒单 --> 查看晒单 : 领完优惠券
查看晒单 --> [*]
@enduml
解析
一、[] --> 与 -->[]
分表表示起始状态与终止状态。
二、state ... {}
状态是能够包含子状态的。在本例中,晒单有礼不关心订单的其余状态,可使用此语法作简单描述。
时序图是本人最喜欢的UML图,在多团队协做时,可让沟通变得很是高效,全部相关人员都能很快的了解到本身须要负责的地方。
例以下图是品牌列表需求的一个时序图:
PlantUML代码
@startuml
hide footbox
autonumber
actor "用户" as user
participant "APP" as app
participant "服务端" as tag
participant "数仓" as sc
participant "算法" as alg
==点击品牌入口==
user -> app: 点击品牌入口卡片
activate user
activate app
app -> tag: 调用自选品牌数据接口
activate tag
tag --> app: 返回「无自选品牌数据」
deactivate tag
app -> app: 弹出自选品牌窗口
app -> tag: 访问品牌数据接口
activate tag
tag -> sc: 访问数仓排序数据
activate tag
activate sc #orange
sc --> tag: 返回品牌排序结果
deactivate tag
deactivate sc
tag -> alg: 查询用户社区偏好品牌
activate tag
activate alg
alg --> tag
deactivate tag
deactivate alg
tag --> app: 品牌数据(包括默认选项2个)
deactivate tag
app --> user
deactivate app
deactivate user
@enduml
解析
一、autonumber
指定显示序号,方便沟通交流,推荐使用。
二、actor,participant
表示用户和对象。
三、activate user,deactivate user
激活一个对象,终止一个对象。
四、activate sc #orange
这里是个小技巧,能够给一个对象的激活态标注不一样颜色,用于强调。
五、左侧小图中,序号6,7步骤,是在一个激活态上再次激活了一次。这里能够强调是开启线程,进行并发调用。
副歌,所谓重要的部分再多细唱两遍,是一首歌的高潮部分,能够升华中心思想。在详细设计中,咱们从概要设计中选取一些细节和核心部分作进一步的设计。
详细设计就像一首歌的副歌部分(也经常被咱们称为高潮部分),虽然在主歌里有涉及,可是须要重点强调。通常而言,详细设计也是用来回答How-如何解决问题,可是须要抓到整个系统的难点进行重点设计。在UML中我一般会使用时序图、类图和组件图来描述。
看到这个小标题,有同窗会问了,“诶,怎么又是时序图?”。其实,时序图能够上到系统级别的调用过程,也能够下到方法级别的调用过程,甚至能够很是接近代码逻辑。在详细设计中也经常使用,来个示例,你们感觉一下:
PlantUML代码
...//省略
loop 循环订单ids
server -> extend:查询trend_extend是否存在订单
activate server
activate extend
extend -> server: 返回是否已经绑定订单
deactivate extend
...//省略
alt 命中晒单有礼
server->cserver:查询优惠券信息
activate cserver
cserver -> server: 返回优惠券信息
deactivate cserver
server->result:「晒单有礼(最高XX元)」
else 未命中晒单有礼
server->result:「晒单」
end
end
...//省略
代码解析
左侧代码只保留了核心逻辑,以下:
一、loop ... end 表示循环,相似各开发语言中的while语句。
二、alt ... else ... end 表示逻辑判断,相似各开发语言中的if else。
类图是经常使用的UML图,显示出类、接口以及它们之间的静态结构和关系;它用于描述系统的结构化设计。
PlantUML代码
@startuml
interface DuDataFlow {
InfoPosts()
InfoAd()
}
class duDataFlow {
grpc.ClientConn
phpservice.Service
context.Context
InfoPosts()
InfoAd()
}
class grpc.ClientConn{}
class phpservice.Service{}
class context.Context{}
DuDataFlow <|-down- duDataFlow
duDataFlow .> grpc.ClientConn
duDataFlow .> phpservice.Service
duDataFlow .> context.Context
@enduml
代码解析
左侧代码已经很是接近开发语言的类定义和接口定义了。
一、 <|-down- 继承关系
二、.> 依赖关系
详细设计不只仅只有时序图、类图,还能够包括DDL、接口文档、任务分工等模块,这里就再也不展开细说了。
至此设计文档至此离编写代码仅剩一步之遥了!!
若是将编写软件设计文档比做写一首歌。那么需求分析就是一首歌的前奏,前奏是一首歌的基调,必定程度上决定了整首歌的风格;概要设计则是主歌,是一首歌的中心思想,核心主题;详细设计则是一首歌的高潮部分,好听的,重要的部分,固然就得再多唱两遍,加深一下记忆点。
最后,再用几句话概况一下几个UML图的特色:
- 用例图-回答“谁用这个系统作什么事情”
- 活动图-突出流程中的事务扭转,以及每一个泳道的位置与做用
- 状态图-描述一个实体的各类状态,以及状态之间的转化关系
- 时序图-在多团队协做时,让沟通很是高效,也能够是代码逻辑的详细结构
- 类图-代码如何组织,各个类之间的关系
文|BeeOML
关注得物技术,携手走向技术的云端粗体