1. 程式人生 > >uml(unified modeling language)用例圖、類圖、序列圖詳解

uml(unified modeling language)用例圖、類圖、序列圖詳解

uml(unified modeling language)全稱為統一建模語言。

uml主要分為九種圖:

一:用例圖

二:類圖

三:物件圖

四:構件圖

五:部署圖

六:狀態圖

七:順序圖

八:活動圖

九:協作圖

而這9種圖分別是其中最常用的是用例圖、類圖、時序圖這三種。這裡由於篇幅有限,暫時先整理用例圖、類圖、序列圖,另外的6個圖將在之後有時間再出新的部落格講解。

一用例圖:從系統外部看系統功能,定義了系統的需求,但並不描述系統內部對功能的具體實現。

用例圖由四部分組成:用例(use case)、參與者(actor)、系統邊界、關聯

參與者(actor):可以是系統的使用者、也可以是維護者,同時還可以是與該系統有關係的其他系統,通常用人形表示。

用例(use case):是參與者可以體驗的系統服務和功能單元,用橢圓表示。

系統邊界:一個系統與另一個系統之間的界限,而一個系統邊界外的其他與該系統相關的部分稱之為系統環境,用一個矩形框包含系統中的用例來表示,下面會有完整用例圖 來解讀。

關係(relationship):用例圖的關係有四種,分別是關聯、擴充套件、泛化、包含。

1:關聯用來表示參與者與用例的關係,用線條箭頭表示,如下圖:

參與者和用例的關聯例子:(由於visio2013裡的關聯沒有箭頭,我也懶得折騰了,就直接這樣了,下面用紅色箭頭稍微標註了一下,正規的還是要用上方的線條箭頭的)


2:泛化是參與者或者用例之間的關係,用空心箭頭表示,如下圖:

 特別注意箭頭打向父用例或者父參與者!

泛化這個要比其他幾個關係更難理解一點,其實直白的說就是類似繼承,一個子參與者或者子用例繼承父參與者或者父用例,因此繼承了父參與者或者父用例所有的行為、關係以及結構,通常父參與者或者父用例比較抽象,例如人就是一個抽象參與者,它可以分為學生參與者,也可以分為老師參與者,這就是一個泛化的參與者關係。

泛化的例項:


3:擴充套件是用例之間的關係,用來表示用例新增的新的功能或者行為,以此誕生的新用例叫擴充套件用例,原先的用例成為基礎(base)用例,用虛線和線條箭頭表示,中間用<< extend>>(extend可以用擴充套件中文來替換)來表示,如下圖。


擴充套件用例的例子,這裡:


4:包含也是用例之間的關係,用來表示一個用例包含多個用例的情況,一般這種都是一個基礎用例具有比較複雜的功能或者行為,需要分多個用例來完成的情況,和擴充套件一樣式用虛線線條箭頭以及中間用<<include>>(include可以用包含等中文來替換)來表示,如下圖。


包含用例的例子:


完整的用例圖例項:


二類圖:用來定義系統中的類以及類與類之間的關係,是對靜態結構的描述。

類圖(class diagram)通過對系統內的類及其關係進行定義來幫助人們理解系統,是系統分析和設計階段的重要步驟。

先來看看類圖中如何在類圖中表現一個類的例項(php程式碼,其他語言其實大同小異),person類裡擁有各種屬性和方法:

class Person{
public $name;
protected $age;
private $sex;


public function say($name,$age){
echo $this->$name." is ".$this->$age;
}
}
下面是通過上面程式碼用uml類圖轉化表示:

可以看出類在uml類圖中是用一個矩形表示的,類的名稱在最上方,用線條進行分隔,例如上圖類圖表示的類就是名為person的類。

person類名下面是類的屬性和方法,在矩形內也用線條進行分隔!同時方法和屬性都具備public、private、protected三種類型,在uml類圖中分別用+、-、#來表示,屬性和方法都一樣。

對應關係:

+  public

- private

# protected

而屬性後的 :  是該屬性的型別,例如+name: string 代表的就是一個public的name屬性,該屬性是string型別,也就是字串型別。同理#age: int是protected的age屬性,該屬性是int型別,也就是整型,而-sex : int 則是private的sex屬性,該屬性是int型別,也就是整型。

方法後的 : 是該方法返回的型別,上圖例子中沒有返回值,因此為void。

上面的例子是普通的類,下面來看看介面在uml類圖中怎麼表示:

介面程式碼:

interface Usb{
	public function getusb($name);
}
class UsbName implements Usb{
	public function getusb($name){
		echo $name;
	}
}
轉化為uml類圖中的表示:

可以看出介面在uml類圖中的表示其實和普通類相似,只是類名上面加上了<<interface>>或者<<介面>>,而接口裡的類都是public型別,因此都是用+號修飾方法,其他的和普通類一致。

我們再來看看抽象類在uml類圖中的表示方式:

abstract class fruit{
abstract public function apple();
abstract protected function pear($num);
}
上面這個抽象類轉化為uml類圖,如圖有兩種表現形式,一個是類名用斜體,另一個是在下方用{abstract}來表示,其他的部分就和普通類一樣了


上面分別解釋了普通類、介面、抽象類三種情況在uml圖中的表示方式,下面就來看看類與類之間的關係在uml類圖中是如何表示的。

在uml類圖中類與類之間的關係主要有:實現、關聯、泛化、聚合、組合、依賴這六種,下面詳細講解這六種關係!

一:實現

實現一般運用於介面,例如有一個usb的介面,而另一個類usbname對usb介面進行實現就是指這種情況。在uml類圖中這種關係用虛線空心的箭頭表示,注意這個箭頭是指向 介面的,一定不要搞錯!如下圖。


二:關聯

uml類圖中的關聯關係表示的是一個類與另外一個類具有某種聯絡,這種聯絡可以是雙向的,也可以是單向的,雙向的聯絡稱為雙向關聯,用實線表示,或者用雙箭頭實線表示,而單向的聯絡則成為單向關聯,用單箭頭的實線表示。

下圖中表示如下程式碼,這是個單向關聯,商店和商品的關聯,商店出售商品。

class Shop{
	public function sold(){
		...
	}
}
class Commodity{
	public function name(){
		...
	}
}


下面再來看看一個雙向關聯的關係,父母與孩子,父母擁有孩子,同時孩子擁有父母,這是雙向關聯:


三:泛化

泛化實際就是一種繼承關係,用來描述子類繼承父類的關係,用空心的實線箭頭來表示,箭頭指向父類!這點需要特別注意,下面是一個簡單的例項,水果是一個父類,而蘋果和梨子則是子類,它們都繼承了水果類。

class fruit{
	...
}
class apple extends fruit{
	...
}
class pear extends fruit{
	...
}

四:聚合

uml的聚合關係表示的是整體與部分的關係,部分是整體的組合部分,但是聚合中的部分是可以獨立於整體存在的,這是一種強關聯關係,例如茶具和杯子就是聚合關係,杯子是茶具的組成部分,但是杯子並不依賴於茶具這個整體,杯子可以獨立存在,這就是一種聚合關係,在uml類圖中聚合用空心的菱形及實線表示,菱形指向整體,如下圖:


上圖表示的就是杯子類和茶壺類與茶具的聚合關係。

五:組合

組合關係和聚合有些類似,也是整體與部分的關係,部分構成整體,但是不同的是組合部分必須依賴於整體存在,如果整體不存在,那麼部分也不存在,組合是關聯的一種,且是一種強關聯,這個強度比聚合更高,在uml類圖中是用實心的菱形實線表示,如下圖:


六:依賴

依賴是指一個事物的變化會影響另一個事物,例如殘疾人和導盲犬之間的關係,這就是一種依賴關係,一般情況下要儘可能的避免產生雙向依賴關係,這個一定要注意,實現、泛化、關聯、聚合、組合都是一種依賴關係,在uml類圖中用虛線箭頭表示,箭頭指向依賴的物件,如下圖:


uml類圖中有些時候需要一定的註解幫助更好的理解,下面是一個範例:

下圖中用的是上面的殘疾人和導盲犬的例子,殘疾人依賴於導盲犬,walk()裡的引數用的是dog類的guiding()方法的返回值,註解可以用以下方式表示:


三序列圖:所謂序列圖就是對物件之間傳送資訊的時間順序進行視覺化。

序列圖由物件(Object)、生命線(Lifeline)、啟用(Activation)、訊息(Message)、分支、從屬流等元素構成。

1)物件(Object):物件便是類的例項,用矩形表示。

2)生命線(Lifeline):是物件存在的時間線,用虛線表示。

3)啟用(Activation):指物件開始執行操作的過程。用長條矩形來表示。

下圖是一個物件及其生命線、啟用的示意圖:


到這裡都還好理解,後面的訊息以及分支從屬流才是重點!

4)訊息(Message):只各個物件間互相傳送訊息,或者互相呼叫,更直白的就是類之間的通訊和呼叫。

訊息根據情況不同分為多種,分別是自關聯訊息、返回訊息、同步訊息、非同步訊息這五種。

1:自關聯訊息:自關聯訊息也叫遞迴呼叫,就是一個物件對自身傳送訊息,用曲線或者折線實體箭頭表示。


2:同步訊息:指的是需要等待發送者進一步操作才能傳送的訊息,用實線實體箭頭表示。


這就類似於按門鈴,在物件沒有按門鈴前,門內的物件是無法進行開門操作的,只有等待門外的物件按門鈴後收到訊息才能進一步繼續,下面的圖詳細介紹了整個流程。

3:返回訊息:顧名思義就是物件之間返回訊息的過程,類似回覆郵件這個過程,用虛線線條箭頭表示。


範例圖:


4:非同步訊息:指的是不需要等待物件進一步操作就可以進行下去的訊息,類似於打電話的過程,撥通號碼後,使用者變不需要繼續下一步的操作,只需等待連線。


5)分支:分支是指從一個點發出多個訊息,這些訊息傳送給不同的物件,並且根據訊息是不是有條件的情況,分為有條件和並行兩種。

6)從屬流:指的是從一個點發出的多個訊息,這些訊息傳送的物件是同一個,但是是在不同的生命線上的情況。

註釋:uml時序圖有時候需要對某些地方進行註釋以此幫助更好的展現各個物件之間傳送資訊的順序。註釋的用法同uml類圖相似,都是用一個矩形翻頁來寫註釋內容,然後用 虛線或者實線連線需要註釋的地方。

約束:約束用來進一步清晰的解釋訊息,例如下圖:


組合片段:組合用來解讀物件之間相互發送訊息的條件和方式,通常用於物件間不同生命線內任何不同條件或者子程序下的訊息通訊。組合片段有非常多種,下面只講解一些比較常見的。

一:抉擇(Alt):抉擇用來表示多個訊息序列下根據不同條件互斥的選擇,類似於if...else,下圖就是一個抉擇的例子,使用者到商店裡購買一件商品,如果小於50件就可以購買成功,如果大於50件,就出現貨品不足無法購買的情況,這是個比較粗糙的例子,不過對於解釋抉擇的組合片段還是很好理解的。


二:選項(Opt):表示一個可能存在又可能不存在的訊息通訊過程,例如上面購買操作,有可能使用者會購買商品,也可能不購買商品,表示如下圖:


三:迴圈(Loop):表示該訊息通訊的過程多次根據條件重複執行,類似於for,如下圖示例:


四:並行(Par):表示物件生命線中持續進行訊息通訊的部分,具體如下圖:


後面還有中斷(Break)、強順序和弱順序三種組合片段。

中斷(break):用來表示序列中如果選擇一個序列則要放棄其他序列的情況,類似於switch裡的break,如下圖:


強順序(strict):多個操作片段必須按照順序發生。下面就是一個典型的例子,做菜這個操作分為切菜和炒菜,這個流程是必須不可逆的,所以是強順序。


弱順序(Seq):多個操作片段在同一生命線上必須按照片段順序發生,如果是不同的生命線則可以是並行發生,這個就不舉例項了,基本表示方法和上面一樣。