本站在上一篇文章中給大家介紹了狀態機圖的相關知識,在這一季中我將帶領大家來了解一下UML中的活動圖。
活動圖是一種用于描述系統行為的模型視圖,它可以用來描述系統的工作流程和并發行為,用于展現參與系統某一行為的類進行的各種活動的順序關系。
活動圖類似于流程圖,可以描述過程邏輯、業務流程和工作流,但活動圖支持并發行為。
下圖是一個活動圖的例子,它對教師的授課過程進行了描述。
從這個活動圖中,我們可以知道一個教師授課的過程包括的主要活動有:起立、復習和提問、講授新課、播放PPT、書寫板書、注意學生行為、與學生互動、總結本次課內容及布置練習和作業等。同時,通過活動圖可以看到各個活動之間的銜接關系內容。
活動圖的主要元素包括動作狀態、活動狀態、組合活動、分叉與匯合、分支與合并、泳道、對象流等。
動作狀態(Action State)是構造活動圖的最小單位,它用于表示原子動作或操作的執行狀態。
動作的原子性決定了動作狀態不能被分解為更小的部分,且動作一旦開始就不能被中斷,直到執行完畢;
動作狀態的執行具有瞬時性,即執行時間極短,甚至可以忽略其執行的時間。
動作狀態沒有內部轉換或內部活動,不能由事件觸發,但可以有轉入,轉入可以是對象流或動作流。
動作狀態包含至少一個轉出。
動作狀態與狀態圖中的狀態不同,它不能有入口動作和出口動作。
在UML中,動作狀態使用下面的圖形來表示:
活動狀態是非原子性的,可以分解成其它子活動或動作狀態,也可以被中斷,占有有限的時間。
活動狀態可以理解為軟件中的一個子過程,而動作狀態則可以理解為基本的處理語句。
如果活動狀態只包括一個動作,則該活動狀態就是動作狀態。因此,可以認為動作狀態是活動狀態的一種特殊情形。
在UML中,活動狀態所使用的的圖形與動作狀態相同,只不過活動狀態可以有入口動作、出口動作和狀態動作等。
下面是活動狀態的一個例子。
這組合活動是一種內嵌活動圖的活動狀態。
把不包含內嵌活動或動作的活動稱為簡單活動。而把內嵌了其他活動或動作的活動稱為組合活動。
組合活動不具有原子性,可以被中斷。
在實際中,組合活動過于復雜會增加理解上的困難,因此,可以把組合活動中的子活動單獨繪制為一個圖。
下面是組合活動的一個例子。
在一些系統中,可能存在著在同一時刻,有兩個或兩個以上的并發控制流的情況。在UML中可以使用同步條來說明這些控制流的分叉(fork)和匯合(joint)情況。
一個分叉是把一個控制流分解成兩個或多個并發的控制流。
匯合表示兩個或多個并發控制流在此取得同步。
在UML中,使用同步條來表示分叉和匯合。
同步條是一條水平或垂直的粗線。
下圖是一個分叉和匯合的例子。
上圖中,在“開始上課”活動之后,使用了分叉,該分叉有一個進入轉移,有多個轉出轉移,“播放PPT”、“書寫板書”和“觀察學生反映”是在授課過程存在同時進行的情況,屬于并發的活動。
這些活動結束后,有一個匯合,這個匯合有多個進入轉移和一個轉出轉移。
分叉的轉出轉移數量應與匯合處的轉入轉移數量相同。
分支(Branch)在程序設計中是一種非常常見的結構,它根據不同的條件進入到不同的路徑中執行。在活動圖中也有類似的處理。
活動圖中也使用一個菱形圖標來表示一個判定。
一般一個判定有一個進入路徑,兩個或兩個以上的轉出路徑。
每個轉出路徑上都有一個監護條件,當監護條件為真時,進入該路徑。
轉出路徑上的監護條件應該是相斥的,不能重疊,且無遺漏的條件。
如“x>=1”和“x>-1”這兩個條件就存在著重疊情況,若滿足兩個路徑上的監護條件時,要進入到哪個轉出路徑呢?
又如“x>0”和"x<0"這兩個條件就存在著遺漏條件的情況,若當“x=0”時,該怎么辦呢?
這些反應到實際系統中,都可能導致系統的錯誤或隱含的BUG。
下圖是一個分支與合并的例子。
在上面這個圖書借閱的例子中,在“獲取讀者借閱信息”活動后有一個判定,如果讀者的借閱數量“達到最大借閱數量”,則執行“停止借閱”活動,否則,圖書館工作人員可以執行“掃描待借書籍”活動,每執行一次這樣的活動之后,也要進行判定,以確保讀者的借閱數量未超過最大借閱數量。
借助活動圖可以清楚的描述業務或處理的過程,但無法清楚的表達這些活動或動作是由誰來完成的。
泳道(Swimlane)技術可以幫助我們解決這一問題,它將活動或動作按執行的對象進行分組,每一組使用泳道來隔開。這樣,即清楚的描述了活動或動作的轉移情況,又表達清楚了這些活動或動作是由誰來完成的。
每個泳道都以對象的名稱或活動者的名稱來命名,這些名稱在一個活動圖中是唯一的。
活動或動作位于泳道內,不可以跨越泳道,而活動的轉移可以跨越泳道。
下圖是使用泳道的一個活動圖。
上圖描述的是一個圖書館工作人員幫助讀者還書的活動圖。從圖中,我們可以清楚的知道,一個還書過程是由“圖書館工作人員”和“讀者”這兩個參與者來完成的,并且知道整個還書過程中,這兩個參與者都做了哪些活動。
可以在活動圖中添加對象,來表示某個活動或動作要使用或輸出的對象。
把涉及到的對象放在活動圖中,使用依賴關系將對象鏈接到對它們進行創建、撤銷或修改的活動轉換上。這種活動與對象的依賴關系和對象的應用被稱之為對象流(Object Flow)。
對象流可用于的場景:動作狀態對對象的使用以及動作狀態對對象的影響。
從對象指向活動或動作的鏈接代表活動或動作在處理時要使用的對象。
從活動或動作指向對象的鏈接表示活動或動作輸出的對象。
在UML中使用一個矩形框來表示一個對象。名稱可以直接使用對象的名稱,也可以使用“對象名:所屬類名”的方式來命名。使用虛線箭頭反向動作與對象之間的依賴關系。
對象中可包含對象所處的狀態。
下圖是一個包含對象流的活動圖。
上圖中的“oBook:Book”、“oBorrowRecords:BorrowRecords”和“oFineRecords:Fine”是對象,在“[]”中的內容是表示對象所處的狀態。
“掃描待還書籍”將產生一個圖書的對象,并修改圖書狀態為“在架”,“確認還書”時將修改借閱記錄,更新借閱記錄中的還書日期等信息,修改圖書的狀態為“在架”。
(1)描述一個操作執行過程中所完成的工作,說明角色、工作流、組織和對象是如何工作的。
(2)對用例的工作流進行建模。說明用例的實例是如何執行動作以及如何改變對象狀態。
(3)幫助相關人員理解業務處理過程。
(4)描述復雜過程的算法。
活動圖用于對系統的動態行為建模。
在建模時,通常選擇對業務流程建?;驅τ美慕换ミM行建模。
對業務流程建模時,可以遵循以下步驟:
(1)選擇要描述的業務過程,找出業務過程中的關鍵對象或參與者,將重要的對象或參與者從左到右依次排開;
(2)為反應動作狀態的執行者,為這些對象或參與者添加泳道;
(3)找出業務的關鍵動作狀態或活動節點,在對應的泳道中添加動作狀態或活動;
(4)確定業務的起始點及結束狀態,為活動圖添加初始狀態和結束狀態;
(5)從起始狀態開始,按照動作的發生次序,依次添加到活動圖中;
(6)連接動作狀態,并根據業務情況,添加分叉與匯合、分支與合并等節點;
(7)如需描述對象的情況,使用對象流來補充活動圖。
(8)審查活動圖中是否有遺漏或需要進一步說明的地方,是否需要使用另外一個活動圖進一步描述某些活動。
對用例進行活動圖建模時可以遵照以下基本步驟:
(1)選定要建模的用例,確定用例執行的基本流程;
(2)通過用例的事件流找出參與者的主動動作,把這些動作整理為活動圖中的動作狀態或活動狀態;
(3)為參與到用例基本流程的參與者和系統添加泳道;
(4)把動作狀態和活動狀態添加到對應的泳道中;
(5)使用分叉與匯合、分支與合并來描述用例執行中的并發動作和特殊事件的備選動作;
(6)審查活動圖是否符合實際情況,是否有遺漏,以及是否需要借助另外一個活動圖來描述活動的情況。
在UML中,可以在用例視圖、邏輯視圖中創建活動圖,也可以給一個用例、一個類、一個接口、一個類的操作等創建活動圖。
在邏輯視圖或用例視圖或一個具體的用例、類上等右擊,然后選擇“New”(新建)—>“Activity Diagram”(活動圖)。
如下圖所示的操作。
用戶可以在創建活動圖的時候,直接給活動圖命名,也可以通過如下方式給活動圖重新命名。
(1)在重新命名的活動圖上右擊,然后選擇“Rename”;
(2)選中要重新命名的活動圖,然后再點擊一下,這時可以給其輸入一個新的名稱。
創建完活動圖后,雙擊打開創建的活動圖,則在對象瀏覽器和繪圖區中間部分顯示創建活動圖用到的基本繪圖工具。
用戶可以在工具箱上右擊,然后選擇“Customize...”來定制工具箱,如把對象、依賴箭頭等添加到工具箱中來。
Rose中提供的活動圖工具箱全部內容如下:
在活動圖工具箱中選擇“Activity”(添加活動)工具,在繪圖區中點擊一下,即完成圖形的創建,然后可以通過下面的某一種方式對該動作狀態進行相關屬性的設置。
(1)雙擊創建的動作狀態;
(2)右擊創建的動作,然后選擇“Open Specification...”。
上面兩種操作方式都可以打開如下圖所示的對話框:
在上面的對話框的“Name”(名稱)中輸入動作/活動狀態的名稱,也可以在“Documentation”中輸入對該狀態的描述內容。
如果創建的是動作狀態,這些信息足夠了。
如果創建的是活動狀態,也可以在Actions選項卡中設置對應的事件動作,這里與狀態圖中狀態的Actions設置相同,在這里不再贅述。
在“Transitions”選項卡中可以查看與該狀態有關的控制流轉換。
在“Swimlanes”選項卡中可以查看該狀態所處的泳道。
在工具箱中選擇“State Transition”(活動/動作轉換)工具,然后在源狀態上按下鼠標左鍵,在不松開鼠標的情況下移到目的狀態上,并松開鼠標,這時就創建了一個狀態之間的轉換。
如果創建的是一個自轉換,就在工具箱中選擇“Transition to self”(自轉換)工具,并在發生自轉換的狀態上點擊一下,則完成了創建。
在工具箱中選擇“Swimlane”(泳道)并在繪圖區點擊一下,即完成了泳道的創建。
在創建時,可以直接對泳道進行命名,也可以通過雙擊泳道名稱的位置,在彈出的對話框中的“Name”處輸入泳道的名稱。
創建的泳道如下圖所示。
每次創建泳道時,默認從左到右依次排列,如果想移動泳道的位置,可以通過下面的方式進行操作:
在要移動的泳道的頭部按下鼠標左鍵,然后移動泳道到指定的位置松開鼠標即完成了泳道的移動。
移動過程如下圖所示:
分叉與匯合,分支與合并的創建與上面的過程相似,在此不再贅述。
在創建分支時,在判定的轉出箭頭的線上可以通過雙擊為其添加轉出發生的事件和參數。這與狀態機圖中的轉移相同。
當然,在其它動作狀態或活動狀態中也可以創建類似的事件和參數等內容。
在工具箱中選擇“Object”(對象,如沒有需要使用上面所講的定制工具箱的方法把它以及依賴添加到工具箱中),然后在繪圖區,點擊一下即完成了對象的創建。
創建的對象默認形狀如下:
用戶在創建的同時可以給對象命名,也可以使用雙擊對象圖形或右擊后選擇“Open Specification...”打開如下圖所示的對話框。
在“General”選項卡中可以設置對象的如下內容:
(1)Name:對象的名稱;
(2)Class:對象所屬的類;
(3)State:對象的狀態;
(4)Stereotype:對象的構造型;
(5)Documentation:描述文檔;
(6)Persistence:對象的持久性,包括持久的,靜態的和臨時的三種;
(7)Multiple instance:是否多個實例。
常用的就是設置名稱,對象所屬的類以及對象的狀態。
在“Incoming Object Flows”和“Outgoing Object Flows”中可以查看流入的轉移和流出的轉移。
作為本文的結尾,這里將給出兩個例子用于說明活動圖的實際使用的情形。
第一個例子用于說明圖書館借閱系統中圖書館工作人員幫助讀者借書的一個業務過程。
第二個例子說明計算讀者圖書超期時計算罰款額度的計算過程。
圖書館工作人員幫助讀者借書時的流程如下:
(1)讀者刷取一卡通;
(2)系統讀取讀者的信息和借閱信息;
(3)讀者有超期圖書時,系統提示需要歸還圖書并繳納罰款后才可以借閱;
(4)讀者沒有超期圖書,但有欠款時,系統提示不能借閱;
(5)圖書館工作人員掃描讀者的每本待借書籍;
(6)系統獲取圖書信息并將圖書信息顯示到待借列表中;
(7)圖書館工作人員掃描完待借圖書后,確認借閱,則完成該次借閱過程。
使用活動圖描述如下:
計算讀者圖書超期的罰款金額步驟如下:
(1)獲取讀者信息;
(2)獲取讀者的超期圖書記錄;
(3)從超期圖書記錄中取一條記錄;
(4)計算該書的超期天數;
(5)該書的罰款金額=超期天數×超期罰款金額單位數量;
(6)將該書的罰款金額累加到罰款金額變量中;
(7)對每本超期圖書重復進行(4)-(6)步;
(8)輸出超期罰款金額。
使用活動圖描述如下:
以上內容介紹了UML中活動圖的相關知識及在Rose中繪制活動圖的方法,如有問題,請在文后留言。
新聞熱點
疑難解答