正如任何生物同樣,軟件也有孕育,誕生,成長,成熟以及衰亡的生命過程,常稱爲「軟件生命週期」。軟件生命週期通常分爲幾個階段:既制定計劃、需求分析、設計、編碼、測試、運行和維護。而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
關注得物技術,攜手走向技術的雲端粗體