1. 概述
軟件建模與設(shè)計(jì)過程可拆分為需求分析购对、概要設(shè)計(jì)和詳細(xì)設(shè)計(jì)三個(gè)階段猾昆。我們往往需要在不同階段輸出不同的設(shè)計(jì)文檔。這個(gè)過程骡苞,除了自身的業(yè)務(wù)理解能力外垂蜗,建模工具UML必不可少,其中常用的有七種(“七武器”):類圖解幽、用例圖么抗、時(shí)序圖、活動(dòng)圖亚铁、狀態(tài)圖、組件圖和部署圖螟加。
適用階段 | 模型圖 | 說明 |
---|---|---|
需求分析: | ||
類圖 | 關(guān)注領(lǐng)域?qū)ο笞R(shí)別及其關(guān)系 | |
活動(dòng)圖 | 描述業(yè)務(wù)流程 | |
用例圖 | 通過反映用戶和軟件系統(tǒng)的交互來描述系統(tǒng)的功能需求 | |
時(shí)序圖 | 通常用于表示對(duì)象之間的交互’這個(gè)對(duì)象可以是類對(duì)象,也可以是更大粒度的參與者’如組件徘溢、服務(wù)器、子系統(tǒng)等 | |
狀態(tài)圖 | 描述狀態(tài)變遷的邏輯關(guān)系 | |
概要設(shè)計(jì): | ||
活動(dòng)圖 | 描述子系統(tǒng)和組件的交互 | |
時(shí)序圖 | 通常用于表示對(duì)象之間的交互’這個(gè)對(duì)象可以是類對(duì)象,也可以是更大粒度的參與者’如組件捆探、服務(wù)器然爆、子系統(tǒng)等 | |
組件圖 | 粒度比較粗,通常用以描述和設(shè)計(jì)軟件的模塊及其之間的關(guān)系黍图,需要在設(shè)計(jì)早期階段畫出來 | |
部署圖 | 是整個(gè)軟件設(shè)計(jì)模型中比較宏觀的一種圖曾雕,是在設(shè)計(jì)早期就需要畫的一種模型圖;還可以估算服務(wù)器和第三方軟件的采購(gòu)成本 | |
詳細(xì)設(shè)計(jì): | ||
類圖 | 開發(fā)工程師按照類圖實(shí)現(xiàn)代碼即可 | |
狀態(tài)圖 | 這個(gè)時(shí)候狀態(tài)要用枚舉值表示助被,以指導(dǎo)具體的開發(fā) | |
時(shí)序圖 | 常用于描述系統(tǒng)內(nèi)部詳細(xì)的接口調(diào)用時(shí)序或業(yè)務(wù)模塊數(shù)據(jù)流轉(zhuǎn)過程 | |
活動(dòng)圖 | 可用于描述一個(gè)類方法內(nèi)部的計(jì)算流程 |
2. 工具選型
2.1. UML工具
繪圖工具總體分為兩類剖张,一類是可視化工具切诀,一類是文本化最終編譯為圖片,以下是我用過的工具對(duì)比搔弄。
名稱 | 類型 | 優(yōu)點(diǎn) | 缺點(diǎn) |
---|---|---|---|
Visio | 可視化工具 | 功能齊全幅虑,有模板 | 連接線對(duì)于手殘黨不友好 |
Visual Paradigm | 可視化工具 | 功能齊全,有模板顾犹,專業(yè)倒庵,號(hào)稱能用最新少鼠標(biāo)點(diǎn)擊完成畫圖操作,默認(rèn)風(fēng)格優(yōu)美 | 最新版非免費(fèi) |
processon | 可視化工具 | 功能齊全炫刷,有模板擎宝,能多人在線協(xié)作,有APP版本 | 非免費(fèi)浑玛,網(wǎng)頁體驗(yàn)不好 |
PlantUML | 文本化工具 | 支持的模型圖功能齊全绍申,免費(fèi),手殘黨福音锄奢,相比拖拽繪圖工具更利于專注業(yè)務(wù)建模,gitlab上提交的markdown文件可直接渲染出圖片 | 依賴Graphviz失晴,默認(rèn)樣式丑 |
mermaid | 文本化工具 | 免費(fèi),很多markdown編輯器默認(rèn)支持拘央,默認(rèn)樣式優(yōu)美涂屁,手殘黨福音,相比拖拽繪圖工具更利于專注業(yè)務(wù)建模 | 支持的模型圖較少 |
最后灰伟,個(gè)人選擇plantUML拆又,它支持常用的七種UML圖,通過定制樣式也可以很優(yōu)美栏账,當(dāng)然帖族,最重要的是不用耗費(fèi)部分精力在畫圖這個(gè)事情上。
PlantUML語法說明詳見>>
2.2. 設(shè)計(jì)編寫工具
2.2.1. 功能訴求
- 支持markdown挡爵。
- 支持markdown中渲染預(yù)覽plantUML竖般。
- 支持導(dǎo)出成HTML、PDF格式茶鹃。
- 支持粘貼保存截圖涣雕。
2.2.2. 工具選擇
名稱 | 類型 | 說明 |
---|---|---|
Visual Studio Code | 文本編輯器 | 獨(dú)立安裝,功能繁多闭翩,忽略介紹 |
Markdown Preview Enhanced | vsCode 插件 | 支持markdown預(yù)覽挣郭、支持plantUML渲染、支持導(dǎo)出HTML和PDF疗韵、支持快速生成目錄 |
Markdown-index | vsCode 插件 | 自動(dòng)根據(jù)markdown標(biāo)題生成或更新順序數(shù)字 |
Paste Image | vsCode 插件 | 支持粘貼保存圖片并轉(zhuǎn)為markdown圖片語法 |
Graphviz | 圖渲染工具 | 需要單獨(dú)下載安裝(否則markdown preview enhanced中的plantuml無法渲染)兑障,并配置好環(huán)境變量GRAPHVIZ_DOT,取值如:D:\Software\Graphviz\bin\dot.exe |
3. “七武器”使用示例
以常見的電商下單支付場(chǎng)景為例,畫出需求分析流译、設(shè)計(jì)過程中涉及的七種UML圖逞怨。
使用PlantUML語法做出參考模板,并進(jìn)行一定程度的美化(仿Visual Paradigm默認(rèn)樣式)先蒋。
3.1. 類圖
刻畫需求分析階段的領(lǐng)域模型或者詳細(xì)設(shè)計(jì)階段的類圖骇钦。
3.1.1. 對(duì)象圖刻畫領(lǐng)域模型
@startuml
' ========調(diào)整樣式=============
skinparam object {
BackgroundColor #70CFF5
BorderColor #black
ArrowColor #black
}
' ========停止屬性的可訪問性樣式=============
skinparam classAttributeIconSize 0
' ========定義模型=============
object 訂單{
- 單號(hào)
- 訂單狀態(tài)
- 金額
}
object 訂單明細(xì) {
- 商品
- 價(jià)格
- 數(shù)量
- 金額
}
object 售后單{
- 類型
- 單號(hào)
- 狀態(tài)
}
' ========定義關(guān)系=============
訂單 "1"*-right-"n" 訂單明細(xì)
訂單 "1" o-down-"n" 售后單
@enduml
image.png
3.1.2. 類圖刻畫代碼模型
@startuml
' ========調(diào)整樣式=============
skinparam class {
BackgroundColor #70CFF5
BorderColor #black
ArrowColor #black
}
skinparam object {
BackgroundColor #70CFF5
BorderColor #black
ArrowColor #black
}
' ========定義模型=============
enum 訂單狀態(tài){
待付款
待發(fā)貨(已付款)
已發(fā)貨
交易完成(已確認(rèn)收貨)
售后中
交易關(guān)閉
已取消
}
class 訂單{
- 單號(hào) : string
- 訂單狀態(tài) : enum
- 金額 : double
+ 創(chuàng)建()
+ 支付()
+ 發(fā)貨()
+ 確認(rèn)收貨()
}
class 訂單明細(xì) {
- 商品代碼 : string
- 商品名稱 : string
- 價(jià)格 : double
- 數(shù)量 : double
- 金額 : double
}
class 售后單{
- 類型 : enum
- 單號(hào) : string
- 狀態(tài) : enum
}
class 售后單明細(xì){
}
' ========定義關(guān)系=============
訂單 "1"*-right-"n" 訂單明細(xì)
訂單 "1" o-down-"n" 售后單
售后單 "1"*-right-"n" 售后單明細(xì)
@enduml
image.png
3.2. 活動(dòng)圖
使用活動(dòng)圖刻畫訂單業(yè)務(wù)流程。
@startuml
' ========調(diào)整樣式=============
' 單個(gè)狀態(tài)定義示例:state 未提交 #70CFF5 ##Black
skinparam activity {
BackgroundColor #70CFF5
BorderColor #black
ArrowColor #black
}
skinparam activityDiamond {
BackgroundColor #70CFF5
BorderColor #black
}
' ========定義流程=============
|用戶|
start
:篩選商品;
split
:添加購(gòu)物車;
:進(jìn)入購(gòu)物車;
:購(gòu)物車結(jié)算;
split again
:立即結(jié)算;
end split
:下單支付;
if (超時(shí)未支付) then (是)
:系統(tǒng)取消訂單;
note right
訂單狀態(tài):已取消
end note
stop
else (否)
repeat
:選擇付款方式;
:確認(rèn)支付;
repeat while(支付失敗)
endif
:支付成功;
note left
訂單狀態(tài):待發(fā)貨
end note
|商家|
switch (商品庫存)
case (沒貨)
:聯(lián)系用戶取消訂單;
: 取消訂單;
stop
case (部分缺貨)
:缺貨部分補(bǔ)發(fā);
case (庫存充足)
:備貨;
endswitch
:物流交接;
:通知發(fā)貨;
|物流|
:運(yùn)輸;
:配送;
|用戶|
:確認(rèn)收貨;
stop
@enduml
image.png
3.3. 狀態(tài)圖
@startuml
' ========調(diào)整樣式=============
' 單個(gè)狀態(tài)定義示例:state 未提交 #70CFF5 ##Black
skinparam state {
BackgroundColor #70CFF5
BorderColor #black
ArrowColor #black
}
'連線樣式:默認(rèn)彎曲竞漾、ortho-折線眯搭、polyline-斜線
'skinparam linetype polyline
' ========定義流程=============
[*] -right-> 待付款 :下單
待付款 : initial
待付款 -right-> 待發(fā)貨 : 支付
待發(fā)貨 : paid
待發(fā)貨 -right-> 已發(fā)貨 : 商家發(fā)貨
已發(fā)貨 : shipped
已發(fā)貨 -right-> 交易完成 : 已收貨
交易完成 : received
待付款 -down-> 已取消 : 超時(shí)未支付
已取消 : canceled
待發(fā)貨 -down-> 已取消 : 商家無貨
交易完成 --> 售后中: 退/補(bǔ)/換貨
售后中 : applying
售后中 -right-> 交易關(guān)閉 : 完成退款
交易關(guān)閉 : closed
交易關(guān)閉 -> [*]
已取消 --> [*]
@enduml
image.png
3.4. 時(shí)序圖
以支付接口交互為例
箭頭規(guī)則參照Visual Paradigam:同步調(diào)用=實(shí)線+實(shí)心粗箭頭;返回值=虛線+細(xì)箭頭业岁;異步調(diào)用=實(shí)線+細(xì)箭頭鳞仙。
@startuml
' ========調(diào)整樣式=============
' 單個(gè)狀態(tài)定義示例:state 未提交 #70CFF5 ##Black
skinparam sequence {
ArrowColor red
LifeLineBorderColor blue
LifeLineBackgroundColor #A9DCDF
ParticipantBorderColor #black
ParticipantBackgroundColor #70CFF5
}
' ========定義流程=============
APP -> APP : 篩選并下單
activate APP
deactivate APP
autonumber 1
activate 訂單服務(wù)
APP -> 訂單服務(wù) : 調(diào)用準(zhǔn)備支付接口
activate APP
alt 首次調(diào)用
autonumber "<b>'1.1.'0"
訂單服務(wù) -> 訂單服務(wù) : 支付申請(qǐng)單 [類型-付款,狀態(tài)-處理中]
訂單服務(wù) -->> APP : 返回業(yè)務(wù)的支付信息
else 二次調(diào)用
autonumber "<b>'1.2.1.'0"
alt 支付申請(qǐng)單[處理中]
訂單服務(wù) -->> APP : 直接返回業(yè)務(wù)的支付信息
else 支付申請(qǐng)單[處理失敗]
autonumber "<b>'1.2.2.'0"
訂單服務(wù) -> 訂單服務(wù) :更新交易憑證號(hào)笔时,且置支付申請(qǐng)單 [狀態(tài)-處理中]
訂單服務(wù) -->> APP : 返回業(yè)務(wù)的支付信息
end
end
deactivate APP
deactivate 訂單服務(wù)
autonumber 2
APP -> 第三方支付平臺(tái) : 調(diào)用支付前提交接口
activate 第三方支付平臺(tái)
activate APP
alt 網(wǎng)絡(luò)異常
autonumber "<b>'2.1.'0"
第三方支付平臺(tái) -->> APP : 網(wǎng)絡(luò)異常棍好,**轉(zhuǎn)步驟2**
else 調(diào)用失敗
autonumber "<b>'2.2.'0"
第三方支付平臺(tái) -->> APP : 返回失敗信息
activate APP
APP -> 訂單服務(wù) : 調(diào)用記錄失敗結(jié)果接口
activate 訂單服務(wù)
訂單服務(wù) -> 訂單服務(wù) : 支付申請(qǐng)單 [狀態(tài)-處理失敗]
訂單服務(wù)-->> APP : 明確返回記錄成功,**轉(zhuǎn)步驟2**(失敗需要重試)
deactivate 訂單服務(wù)
deactivate APP
else 調(diào)用成功
autonumber "<b>'2.3.'0"
第三方支付平臺(tái) -->> APP : 返回提交成功結(jié)果,**轉(zhuǎn)步驟3**
end
deactivate APP
deactivate 第三方支付平臺(tái)
autonumber 3.1
APP -> 第三方支付平臺(tái) : 調(diào)用確認(rèn)支付接口
activate 第三方支付平臺(tái)
activate APP
alt 網(wǎng)絡(luò)異常
autonumber "<b>'3.1.1.'0"
第三方支付平臺(tái) -->> APP : 網(wǎng)絡(luò)異常允耿,**轉(zhuǎn)步驟3.1**借笙,進(jìn)行重試
else 調(diào)用失敗
autonumber "<b>'3.1.2.'0"
第三方支付平臺(tái) -->> APP : 返回失敗信息,**轉(zhuǎn)步驟2.2.1**较锡,記錄失敗結(jié)果
else 調(diào)用成功
autonumber "<b>'3.1.3.'0"
第三方支付平臺(tái) -->> APP : 返回完成支付信息业稼,**轉(zhuǎn)步驟3.2**,記錄成功結(jié)果
APP -> 訂單服務(wù) : 調(diào)用確認(rèn)完成支付
activate 訂單服務(wù)
訂單服務(wù) -> 訂單服務(wù) : 置支付申請(qǐng)單位已完成蚂蕴,\n訂單狀態(tài)為待發(fā)貨
訂單服務(wù) -->> APP : 返回訂單完成支付信息
deactivate 訂單服務(wù)
end
deactivate APP
deactivate 第三方支付平臺(tái)
@enduml
image.png
3.5. 組件圖
@startuml
' ========調(diào)整樣式=============
' 單個(gè)狀態(tài)定義示例: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
}
' ========定義內(nèi)容=============
component [訂單] as order
component [商品] as goods
component [支付申請(qǐng)單] 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
' ========調(diào)整樣式=============
' 單個(gè)狀態(tài)定義示例: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 ' 設(shè)置圓角
}
' ========定義內(nèi)容=============
rectangle 前臺(tái) 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 中臺(tái) #line.dashed;{
cloud 阿里云SLB as slb
node 中臺(tái)網(wǎng)關(guān)云服務(wù)器 as gatewayNode{
component [api-gateweay] as gateway <<API服務(wù)網(wǎng)關(guān)>>
}
node 訂單云服務(wù)器 as orderNode{
component [order-web] as orderWeb <<訂單Web服務(wù)>>
component [order-service] as order <<訂單中臺(tái)服務(wù)>>
}
node 庫存云服務(wù)器 as invNode{
component [inv-service] as inv <<庫存中臺(tái)服務(wù)>>
}
database 訂單中臺(tái)云數(shù)據(jù)庫 as orderDS <<MySQL>>
database 庫存中臺(tái)云數(shù)據(jù)庫 as invDS <<PostgreSQL>>
}
rectangle 后臺(tái) #line.dashed;{
node ERP服務(wù)器 as erp{
component [inv-transfer] as erpInvTransfer <<ERP庫存中臺(tái)交換服務(wù)>>
component [order-transfer] as erpOrderTransfer <<ERP訂單中臺(tái)交換服務(wù)>>
}
database ERP數(shù)據(jù)庫 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. 用例圖
開發(fā)階段用的較少低散,PS:記箭頭關(guān)聯(lián)關(guān)系表示好累 _。
@startuml
' ========調(diào)整樣式=============
' 單個(gè)狀態(tài)定義示例:state 未提交 #70CFF5 ##Black
skinparam usecase {
BackgroundColor #70CFF5
BorderColor #black
ArrowColor #black
}
skinparam actor {
BackgroundColor #70CFF5
BorderColor #black
}
' ========定義內(nèi)容=============
left to right direction
actor "用戶" as user
usecase "網(wǎng)上購(gòu)物" as ecBuy
usecase "下訂單" as order
usecase "搜索商品" as searchGoods
usecase "添加購(gòu)物車" as addBasket
usecase "支付" as pay
usecase "取消支付" as cancelPay
' ========定義內(nèi)容=============
' 箭頭關(guān)系:--> 依賴骡楼, <|--泛化(繼承) ,..> 包含或者擴(kuò)展
user --> ecBuy
ecBuy <|-- order
order ..> searchGoods : <<包含>>
order ..> addBasket : <<包含>>
order ..> pay : <<包含>>
cancelPay ..> pay : <<擴(kuò)展>>
@enduml
image.png