1. 程式人生 > 實用技巧 >UML建模圖實戰筆記

UML建模圖實戰筆記

一、前言

UML:Unified Modeling Language(統一建模語言),使用UML進行建模的作用有哪些:

  • 可以更好的理解問題
  • 可以及早的發現錯誤或者被遺漏的點
  • 可以更加方便的進行組員之間的溝通
  • 支援面向物件軟體開發建模,可以更好的描述顯示程式設計的情景。
  • 對於複雜的系統來說,如果概要模型做的好,那麼整個系統的模型也就很清晰明瞭。

二、 UML介紹

UML 規格定義了兩大類UML圖:結構圖( structure diagrams )和行為圖(behavior diagrams)

結構圖( structure diagrams )
結構圖從不同的抽象和實現程度上描述了一個系統和系統構建的靜態結構,並且描述了他們直接是如何關聯到一起的。

行為圖(behavior diagrams)
行為圖展示了一個系統中的物件的動態行為,它描述了一個系統中的物件如何隨著時間變化而變化。

下面借用下UML2.5官方圖說明下UML圖分類:

領域模型也叫概念模型,是對現實世界概念類的描述,並非軟體物件描述,領域模型不是資料模型。在uml中領域模型被描述為一組沒有操作的類圖,具體說不是Java裡面的軟體物件或者具有職責行為的物件。他可以展現領域物件或概念類,概念類之間關聯,概念類的屬性。
三個要素,類名,屬性 ,關聯。
任何屬性都不表示外來鍵,應該直接使用關聯關聯到外來鍵所在類。

三、用例圖

在軟體生命週期的整個過程中,用例圖是軟體需求分析到軟體交付的第一步,用例圖的主要目的是說明這個軟體的使用者是誰,使用者要使用那些功能,以及使用者需要向軟體提供什麼功能。通過用例檢視一來可以讓使用者清楚的理解這個軟體到底能提供什麼功能,是不是滿足自己的需求,另外一方面對應開發者來說,可以更好地理解需求,從而能更好的去實現這些需求。

用例圖主要有六個元素,分別是:參與者(Actor)、用例(Use Case)、關聯關係(Association)、包含關係(Include)、擴充套件關係(Extend)以及泛化關係(Generalization)。

參與者(Actor)
參與者在uml中用下面帶有名字的小人來標示,主要表示與您的軟體系統互動的人,組織或者外部軟體系統。

用例(Use Case)
用例在uml中用使用橢圓標示,主要說明你的軟體系統的功能,是使用文字描述的形式說明你的系統的功能。

關聯關係(Association)
在uml中用例圖中用箭頭來標示,主要描述參與者與用例之間的關係。
【箭頭指向】:指向用例

包含關係(Include)


在uml中包含關係表示為虛線箭頭交<>字樣,有時候一個用例很大,那麼我們可以把用例分塊,把複雜的用例分解為幾個小用例來描述
【箭頭指向】:箭頭指向被包含的用例

擴充套件(Extend)
在uml中擴充套件關係表示為虛線箭頭加<>字樣,擴充套件是指在基礎用例功能的基礎上插入新的功能點,新的功能點可以看做是對基礎用例的擴充套件。
【箭頭指向】:箭頭指向基礎用例

泛化(Inheritance)
在uml中用例泛化用一個空心三角箭頭從子用例指向父用例,泛化就是繼承關係,子用例可以使用父親用例中的屬性,行為和關係。
【箭頭指向】:箭頭指向父用例

Include、Extend、Inheritance總結對比
包含關係強調整體與部分之間關係,也就是說整體的功能是由一個個子用例功能疊加起來的,比如上圖庭審功能就包含了線上視訊庭審,線上語音庭審,線下語音庭審功能,庭審用例本身是對子功能的彙總標示,具體功能點在子用例實現。

擴充套件關係則強調是在基礎功能的基礎上新增新的功能,基礎功能本身是提供功能的,基礎功能和擴充套件功能直接是不可見的,但是擴充套件功能是要在基礎功能的某一個條件下才會發生,例如上面基礎服務視訊庭審已經提供了庭審的功能,現在有加了了擴充套件的語音識別功能來識別使用者說的話為文字。之所以說是擴充套件功能是因為即便沒有語音識別功能,視訊庭審功能還是照樣可以正常運轉,之所以說擴充套件功能是有條件發生是因為只有開通了語音識別的視訊庭審才能回有語音識別的擴充套件功能

泛化關係則強調複用的關係,也就是說子用例基礎了父用例的一部分功能並且自己有新增了或者覆蓋了父用例的功能,具體說比如上圖視訊庭審有個記錄筆錄的功能,這個本身是個獨立的功能點,而書記員和法官都可以複用這個功能並對其定製化。

一個案例

4、時序圖

時序圖建模工具,推薦一個工具https://www.zenuml.com/

時序圖是一種強調訊息時序的互動圖,他由物件(Object)、訊息(Message)、生命線(Lifeline)和Combined Fragments組成,它主要描述系統中物件和物件之間的互動,它將這些互動建模成訊息交換。

時序圖將互動關係展示成了一個平面二維圖,其中縱向標示時間軸,時間沿豎線從上向下進行。橫向軸標示了互動中各各個物件。物件的的用生命線表示。訊息從一個物件的生命線到另一個物件生命線的箭頭表示,箭頭以時間順序在圖中從上到下排列,從左到右排列。

物件(Object)和生命線(Lifeline)
生命線頭上那個方正的框裡面存放的就是物件,物件有自己的名字,生命線其實就是從上到下的一個虛線。生命線標示一個物件存在的生命週期,兩條生命線中間通過訊息連線起來,

訊息(Message)

訊息用於物件間傳遞資訊,物件之間的資訊互通就是通過訊息,訊息按照分類可分為:同步訊息(Synchronous Message),非同步訊息(Asynchronous Message)和返回訊息(Return Message) 自關聯訊息(Self-Message)

  • 同步訊息:傳送訊息的物件在傳送訊息後會掛住,等訊息接受物件接受訊息返回後才會解除掛住的狀態繼續自己的工作。
  • 非同步訊息:傳送訊息的物件在傳送訊息後會繼續自己的工作,而不等訊息接受物件接受訊息返回。
  • 返回訊息:標示傳送訊息後返回的動作
  • 自關聯訊息:一個物件內自呼叫的情況。

Combined Fragments
標示有一定條件的訊息傳送,

  • Alternative fragment(denoted “alt”) 標示 if…then…else
  • Option fragment (denoted “opt”) 標示Switch
  • Parallel fragment (denoted “par”) 標示同時發生
  • Loop fragment(denoted “loop”) 標示for
  • Break標示退出迴圈

1.loop:
當沒有指定迴圈邊界預設範圍為[0,無窮大]:

如果只指定了一個值,那麼預設執行該值次數:

指定了迴圈邊界,則最少執行最小值值,最多執行最大值次數:

實現dowhile方式,至少執行一次,如果size<0則退出:

2. alt:
條件判斷,如果n>0則執行agree函式否者執行reject函式

3. opt:
switch,當滿足不同條件執行不同方法:

4. break:
n=10時候執行save並退出迴圈

5. par:
同時進行,比如多個執行緒同時執行任務

一個例子

5、類圖

類圖是面向物件系統建模中重要的圖,是定義其它圖的基礎。類圖主要是用來展現軟體系統中的類、介面以及它們之間的靜態結構。

在uml類圖中,類之間關係有如下: 泛化(Generalization), 實現(Realization),關聯(Association),聚合(Aggregation),組合(Composition),依賴(Dependency)

5.1.泛化:
泛化是繼承關係的一種,子類繼承父類的所有行為和屬性,子類可以新增新的功能或者重寫父類功能。
uml中使用帶空心三角箭頭的實線標示
【箭頭指向】:箭頭指向父類

5.2.實現:
實現是介面和類的關係,是指類實現了介面中定義的介面,uml中用帶空心三角箭頭的虛線
【箭頭指向】:箭頭指向介面類


5.3.關聯:
在建模過程中必然存在類之間的聯絡,使類可以感知其他類的行為和屬性,關聯分為雙向和單向關聯

  • 雙向關聯(標準)
    對於雙向關聯來說被關聯的兩個類可以感知對方的存在

    如圖線上每端放置一個角色和多重值,對於Route來說我們應該看在bike端的角色和多重值,對於Route來說每個騎行路線對應0個或者多個自行車,0個是因為可能先制定了騎行路線但是還沒有找到自行車,多個是因為可以有多個人騎行同一個路線。對於bike來說我們應該看route端的角色和多重值,對於一個bike來說每個自行車對於0個或者多個騎行路線,0個是因為雖然有一個自行車但是我可以不騎行,不指定騎行路線那,多個是因為我一個自行車可以指定多個騎行路線。

上面多重值為0…*,其實還有其他多重值如下表:

表示含義
0..1 0個或1個
—- —-
1 只能1個
—- —-
0..* 0個或多個
—- —-
* 0個或多個
—- —-
1..* 1個或多個
—- —-
3 只能3個
—- —-
0..5 0到5個
—- —-
5..15 5到15個
  • 單向關聯
    對於一個單向關聯來說也是兩個類是相關的,但是隻有一個類知道這種聯絡的存在
    如圖對於單向關聯表示為一條帶有指向已知類的開放箭頭實線,單向關聯只包含一個角色名和多重值,一個人可以有0個或者多個賬戶,人可以感知到賬戶的存在,但是賬戶卻感知不到人的存在。
  • 聚合
    聚合是關聯關係的一種,聚合主要描述整體與部分直接的關係,聚合有分為基本聚合和組合聚合,

基本聚合:對應基本聚合來說部分類的生命週期獨立於 整體類 的生命週期,uml中使用一條從整體類到部分類的實線,並在整體類的關聯末端畫一個未填充稜形標示:

一個汽車有4個輪子組成,輪子的生命週期不依賴與車的,因為車輪可以獨立於車獨立存在。

組合聚合:組合聚合是聚合的一種情況,不同在於部分類的生命週期依賴整體類,uml中使用一條從整體類到部分類的實線,並在整體類的關聯末端畫一個填充稜形標示:

一個公司有至少一個部門組成,部門要依賴於公司的存在而存在,不會存在一個部門而它不屬於某一個公司。

  • 自身關聯
    自身關聯涉及到一個類,是類自己關聯自己的情況

一個僱員可以有0個或者多個管理者,而管理者本身也是僱員的一種。

5.4.依賴:
依賴即一個類的實現需要其他類的協助,通常程式碼表現為方法引數,區域性變數,靜態方法呼叫,util類呼叫,uml中使用一條箭頭的虛線,從依賴方指向被依賴的類

一個例子
從UML官方網站搞了個 域模型圖

下面圍繞類Library類分析下這個圖,首先library通過組合方式關聯到了Catalog類目類,這說明類目不能獨立存在要依賴圖書館存在,所以這裡沒有使用聚合而使用了組合。另外library通過聚合關聯到了Book Item 類和Account賬號類,這說明圖書館是有0個或者多個圖書和賬戶組成,這裡使用聚合而不是用組合是因為書和賬號可以獨立於圖書館存在,比如我有學號賬號,但是圖書館裡面不是必然有你的賬號。

下面圍繞Catalog分析,類目通過雙向關聯關聯到bookitem,說明一個類目裡面可能會有0個或者多個書籍,一個書籍對應著一個類目。另外類目有通過realization實現了search類和manage類的介面,讓類目有搜尋和管理功能。Search類搜尋時候會依賴Patron類圖書捐贈人的姓名地址或者Libraian類圖書管理員的姓名地址,職位。 圖書管理類時候會依賴圖書管理員類的資訊。

而Patron圖書捐贈人有可能是一個學生,學生有自己的賬號,所以patron類會聚合到Account.
bookItem類通過泛化繼承Book中書的共性部分資訊。有通過關聯關聯到了account,說明一個賬戶只能接到0本和最多12本書,最多可以預定3本書。

最後Book類雙向關聯到Author類,數目一個作者至少寫了1本書(嚴格說應該是0),一本書至少有一個作者編寫,
Account賬戶類有依賴一個AccountState的列舉值的類用來存放賬號狀態。

6、活動圖(Activity Diagrams)

活動圖是UML中一種行為圖,它展示了控制流和物件流,並且強調它們的順序和條件控制流。
下面換種方法,通過引入uml官方例子同時介紹活動圖裡面元素。

6.1 組元介紹

  • 開始(inital)和結束狀態(final)

  • 活動(action):標示動作
  • 控制流(control flow):連結活動
  • 決策(decison):條件判斷
  • 合併(merge):任意一個節點到達該點都繼續往下走,不管其他分支
  • 游泳道(swimlanes):模型中存在多個物件時候使用比較適合
    分為水平和垂直
  • 分岔匯合(join):所有分支都到該點時候才繼續往下走,類似CountDownLatch.await後在繼續往下走
  • 分流(fork):類似fork多個執行緒執行放入執行緒池執行。
  • 接受訊號(acceptsignal)

6.2 online shopping例子

下面拿uml官方online shopping網上購物例子介紹

如圖左上角黑色圓為活動開始,首先通過decision的條件判斷是進行搜尋還是瀏覽,如果是搜尋則通過merge節點後搜尋商品,然後通過decision節點判斷搜到商品則進入在做決定是瀏覽商品資訊還是加入購物車。加入購物車後可以選擇進入B繼續
搜尋其他商品,或者檢視購物車內容,然後購物完後,進入C進行付款,然後流程結束。

另外可以隨時接受訊號去檢視進入A檢視購物車資訊,也可以隨時收到訊號去checkout商品。

6.3 Activation of Trial Product例子
下面拿uml官方Activation of Trial Product啟用試用產品例子介紹

首先這個活動圖裡面由於模型涉及到了Order Management, Customer Service, Customer三個物件,所以使用了垂直的swimlanes。

首先customer請求啟用自己正在使用的試用期產品(估計試用期過了,不能使用了),然後顧客服務物件通過fork開啟兩個流程,一個流程是讓Order Management建立產品訂單,一個是讓使用者產生C2V檔案。然後Customer Service在 join 處等待兩者完成,這裡都完成在拿著產品祕鑰和C2v檔案去啟用產品,通過email等把檔案傳遞給使用者,使用者拿到檔案既可以啟用,至此活動結束。

7、元件圖

元件圖是為了展示組元(components),組元提供的介面(provided inerfaces)和需要呼叫的介面(required interfaces),埠(ports)之間關係的一種圖,元件圖是主要被用於基於元件開發時候用來描述SOA系統。

7.1 元素介紹

  • 組元(Component)
    組元是代表一個系統中一個模組的類,並且組元的表現(比如實現)在其所在的環境上下文中是可被替換的,組元有自己的行為,比如對外提供介面和使用其他元件介面,這些介面潛在的是通過埠(ports)暴露或者使用。

如圖語音識別服務組元對外提供getPort介面供其他組元呼叫,網上法庭說明自己需要使用getPort介面來實現自己的功能。

  • 埠(port)
    埠表述了一個一個類與它所在的環境或者其他類的一個互動點,

    如圖Accounting組元內部的Customers提供Account服務,而Orders組元則使用Account服務。
  • 連線線(Connector)
    連線線是用來連線兩個或者多個例項使他們直接能夠進行交流協作。主要用來連線兩個埠直接的交流

7.2 一個例子
下面分析下uml官方一個例子

如圖在網上商城系統有三個子系統組成:webstore,accounting,warehouses;
WebStore子系統包含三個組員,搜尋引擎,購物車,認證系統。搜尋引擎組元通過對外提供了一個ProductSearch介面執行其他元件搜尋和檢視商品,另外這介面是搜尋引擎元件使用庫存元件提供的Search Inventory介面來實現。購物車組元則把呼叫訂單組元的的Manage Orders介面的功能封裝下自己對外提供了onllineShopping介面,認證組元則允許使用者建立賬號,登陸或者退出,並且繫結訂單到具體使用者。

accounting子系統對外提供了Manage Orders 和 Manage Customers介面,並且通過代理連線到子系統內部的Orders和customers組元,。Orders組元呼叫了Customers組元的Manager customers介面,Customers呼叫了Accounts組元的Manager Accounts模組。

Warehouses子系統提了Search Inventory and Manage Inventory元件,並且通過依賴方式是要了Accounting子系統的介面服務。

8、狀態圖

狀態機圖是一種行為圖,它通過使用有限的狀態轉移展示了一個系統中一個模組的一些離散的行為,在UML2.4裡面有兩種狀態機圖:行為狀態機(behavioral state machine),協議狀態機(protocol state machine)。

8.1 元素介紹

行為狀態(Behavioral State)

  • 簡單狀態(Simple State)
    簡單狀態沒有子狀態機和域,UML中使用帶拐點的矩形標示簡單狀態,並且狀態名字寫在矩形內部。

  • 組合狀態(Composite State)
    組合狀態被定義為用用子狀態或者巢狀狀態的狀態行為,子狀態可以是順序發生的也可以是併發發生,組合狀態裡至少有一個域,如下圖含有一個域

*__ 起始狀態(Initial Pseudostate),終止狀態(Final State),(行為轉移)Behavioral Transition



如圖黑色實心為起始狀態,末端雙環圓為終止狀態,中間連線線為行為轉移,其中isAuthed為一個guard說明滿足該條件才會進行狀態轉移,然後執行函式auidt。

8.2 行為狀態機(behavioral state machine)

使用有限狀態轉移表示一個系統中的離散行為的變換,行為被建模為通過一系列轉移線連線起來的狀態。
一個簡單的行為狀態機:

8.2 協議狀態機(Protocol State Machine)

協議狀態機是行為狀態機的一個子類,是行為狀態的擴充套件,用來描述一個類的生命週期和協議,他描述一個類的哪一個動作可以被哪一個狀態下的規定條件下被呼叫。

8.3 官方例子

如下圖是一個Java執行緒狀態機圖(協議狀態機圖)

如圖 New狀態是一個執行緒被建立但是沒有執行start()方法時候狀態。
在JVM看來當一個執行緒在Runnable時候它是在執行,但是在os看來卻未必,因為執行緒可能沒有獲取到處理器。所以可以考慮把Runnable看為一個內部有兩個子狀態的組合狀態,當一個執行緒狀態進入Runnable時候,首先進入Ready狀態(其他資源已經就緒,就差cpu),由執行緒排程策略決定何時把這個執行緒從Ready轉變為running狀態,函式Thread.yield() 則知識執行緒排程暫定當前執行緒執行,把執行緒從running狀態轉變為Ready狀態…

九、總結

本文對軟體建模中常用建模圖使用進行簡單介紹,以便用到時候能夠快速查閱。

十、參考

http://www.uml-diagrams.org/