在實際工作中,大部分程序員很少接觸到需求分析,即使有需求分析,也是草草了事,沒有用正規(guī)的方式來表達,所以一般程序員使用用例圖的機會是不多的。但是卻又常常在各種媒體上看見用例圖,于是對一種常常出現(xiàn),自己又不太熟悉的技術(shù),會產(chǎn)生恐懼。如果說對MDA或者CORBA這樣的技術(shù)產(chǎn)生恐懼還是值得的話,對用例圖產(chǎn)生恐懼是非常不值的。因為MDACORBA這樣的技術(shù)也許要花上半年的時間才能夠初步了解,而克服用例圖恐懼癥,則只要不到一天的時間。

用例圖初感

UML是一組圖示符號的標準。所謂圖示符號,就是一組定義好的圖示,它們可以表達定義好的各種意思。用UML進行軟件建模,就是用規(guī)定好的符號畫圖,這些圖表達了開發(fā)人員腦中的軟件系統(tǒng)。用UML進行軟件建模,其難度并不比我們小時候上的美術(shù)課更難。在美術(shù)課上,一個圓形加上四根線條表示太陽,一個三角形加上一個矩形表示房子;同理,在UML的用例圖中,一個橢圓表示用例,一個小人表示參與者。我并不認為它們之間有質(zhì)的區(qū)別,想到我對這種小學(xué)生畫圖課恐懼了幾年,不由得感到羞愧。

用例圖是UML的九個圖中較為重要和常用的一種圖。常常用于軟件開發(fā)的需求分析階段,也能用于軟件的系統(tǒng)測試階段。簡單的來說,用例圖是描述系統(tǒng)的外部視圖。

在開始設(shè)計一個軟件系統(tǒng)時(更廣義的情況下,可以用來設(shè)計任何系統(tǒng)),需要一種手段來發(fā)現(xiàn)系統(tǒng)的功能,用例圖雖然是圖示,但是這些圖示隱含了一種啟發(fā)系統(tǒng)功能的手段。其實所有的UML圖都只包含圖示和標準,并不包含方法,但是它們往往隱含了某種方法。UML和軟件開發(fā)方法的關(guān)系,很類似于漢字和語文的關(guān)系。

用例圖包含了三種基本的概念:用例、角色和系統(tǒng)。它們可以組合起來表達系統(tǒng)的外部視圖。而且這種表達方式是如此直觀和簡單。

第一張用例圖

畫用例圖是一件很簡單的事情,而且感覺還很舒適,因為用例圖簡潔、直觀。雖然用例圖不能像HelloWorld一樣運行,也不能生成代碼,不過畫一張清晰的用例圖還是很有成就感的。

我使用的工具是Eclipse+EclipseUML插件,功能不如Rose,但是是開源而且免費的(EclipseUMLfree版也有企業(yè)版),而且效果也不錯。第一張用例圖如下:

第一張用例圖.jpg可以看出圖中有一個系統(tǒng)(保險商務(wù)系統(tǒng)),兩個角色(客戶和保險銷售員)以及三個用例(簽訂保險單、銷售統(tǒng)計資料、客戶數(shù)據(jù)資料),另外還有四個連接線以及一個注釋。如果在紙上或者合適的工具中,畫這樣一張用例大概只需要五分鐘吧。不過僅僅畫出來是沒有意義的,需要弄清楚其背后真正的含義才行。

理解用例圖

可以這樣簡單的理解用例圖中的一些概念,系統(tǒng)System)指的是軟件系統(tǒng),它可以包含一些用例,并界定系統(tǒng)的邊界,邊界之內(nèi)的屬于系統(tǒng)的功能和行為,邊界之外的則不是系統(tǒng)所關(guān)心的內(nèi)容。系統(tǒng)規(guī)定了一個具有某些功能的黑盒子,在系統(tǒng)之外看到的僅僅是這個系統(tǒng)的功能,而不能看到系統(tǒng)的內(nèi)部細節(jié)。這一點也是用例圖經(jīng)常被用來做系統(tǒng)測試的原因。當然這些測試一般是黑盒測試。

角色Actor)是與系統(tǒng)中的用例交互的一些實體,在實際情況中,角色可以是人,也可以是其他系統(tǒng)或者硬件設(shè)備。在畫用例圖的過程中,角色往往是第一個被確定的,因為系統(tǒng)或者用例在開始時是模糊的,但是參與系統(tǒng)的角色是最容易明晰的。有了角色之后,根據(jù)角色與系統(tǒng)的交互,以及角色要求的功能,可以進一步確定系統(tǒng)和用例。

用例Use case)指的是系統(tǒng)的功能,它是系統(tǒng)某個功能的所有執(zhí)行動作的集合。在UML圖示中它是一個橢圓,但是具體分析用例的時候需要給出這個用例的所有執(zhí)行動作的步驟。例如上圖中的“簽訂保險單”用例,就可以分為幾個步驟:第一,客戶發(fā)出保險單請求;第二,系統(tǒng)給出保險單樣式表;第三,用戶填寫保險單樣式表;第四,系統(tǒng)檢查用戶提交的保險單格式是否規(guī)范;第五,如果不規(guī)范則返回第二步,如果規(guī)范則給保險單銷售員發(fā)出消息;第六,保險單銷售員填寫保險單;第七,保險單銷售員將填寫好的保險單加入數(shù)據(jù)庫,并將客戶資料輸入客戶數(shù)據(jù)庫。當然,以上步驟僅僅是我想象的,我還從來沒有見過什么“保險單”,這次過了一把癮。

連接Assocation)是角色與用例的連接,表達此角色可以初始化此用例。 

注釋Note)可以添加到任何地方,對用例圖的不同部分加以說明。

泛化、包含和擴展

泛化Generalization)在面向?qū)ο蟮募夹g(shù)中無處不在,它的另一個名字也許更為著名,就是“繼承”。下圖給出了一個使用泛化的用例圖:

繼承關(guān)系用例圖.jpg由此可知,在用例圖中,角色和用例都能夠泛化。角色的泛化/繼承很容易理解,因為角色本來就是類(Class),它是一種版型(stereotype)為Actor的類,所以角色的繼承直觀而自然。但是用例的繼承實際上分為兩種情況,并不是簡單的使用泛化,而是使用擴展(extended)和包含(include)兩種泛化的特例。

擴展用于子用例的動作步驟基本上和父用例的動作步驟相同,只是增加了另外的一些步驟的情況下。包含用于子用例包含了所有父用例的動作,它將父用例作為了自己的一個大步驟,子用例常常包含一個以上的父用例。如下圖:

用例的擴展和包含.jpg小結(jié)

關(guān)于用例圖基本上也就是上面提到的這些內(nèi)容了。當然,用例圖還常常和類圖、活動圖聯(lián)合使用,不過那些知識還是等其他知識完備了以后再說比較好。

我總結(jié)的畫用例圖的步驟如下:

l         確定系統(tǒng),擬出系統(tǒng)的名稱,這個不難,例如電信計費系統(tǒng);

l         找出所有與系統(tǒng)打交道的角色,角色要進行一些精簡和整合;

l         站在角色的立場想象系統(tǒng)應(yīng)該提供的功能,將這些功能畫成系統(tǒng)中的用例;

l         對于每個用例給出詳細的動作步驟;

l         找出用例圖中角色、用例之間可能有的繼承、擴展或者是包含關(guān)系;

以我現(xiàn)在的理解能力,認為用例圖到此為止了。當然,我還可以想象,用例圖會用來啟發(fā)類圖的構(gòu)建,例如用例圖中的某些部分(角色或者用例)會變成類圖中的類或者接口。另外,可以想象用例圖還可能會影響活動圖中的流程。

后記

讓我恐懼了好久的用例圖在今天便土崩瓦解了,心中卻彷佛有一點茫然,因為我記得自己無數(shù)次的對自己說“好忙啊,這個技術(shù)肯定要花很多時間,還是以后再學(xué)吧”類似的話。當我用C的時候?qū)?/SPAN>C++這樣說過,然后是JavaCORBAJSPXMLMDAXMIUML……

blog不僅僅是一種愛好,對我來說,更是一種最好的學(xué)習(xí)方法,當我讀小學(xué)的時候,班主任常常對我說“好記性不如爛筆頭”,我當時的理解是把事情用筆記下來比用腦袋背下來更加持久(腦袋是內(nèi)存?紙筆是數(shù)據(jù)庫?)。但是,現(xiàn)在我理解到,要學(xué)習(xí)某個東西,最好的方法是用自己的語言把它表達出來,如果你能讓別人理解這個技術(shù),你自己當然已經(jīng)精通了。在我寫blog的過程中,常常會出現(xiàn)寫到一半的時候猛然領(lǐng)悟的情況,這是因為當你在選擇最佳的表達方式的時候,將你自己頭腦中一團亂麻的線索都理清了的結(jié)果。

有朋友留言說,自己計算機本科畢業(yè),在計算機領(lǐng)域?qū)W習(xí)了八年,竟然看不懂我的blog。這個我認為很正常,讀本科的時候,所有同學(xué)都可以在一起討論問題、實習(xí);等到上研的時候,同學(xué)對我說他的課題,我只能模糊的聽個大概,因為專業(yè)方向已經(jīng)分開了;現(xiàn)在讀博了,同學(xué)要拉著我說他的課題,我只能明白是哪個領(lǐng)域里面的問題,往往對這個問題的描述都聽不懂了。這是因為研究方向已經(jīng)非常精細的原因。我自問我的方向已經(jīng)很大眾化了,如果研究圖像壓縮算法的話,那滿篇都是數(shù)學(xué)公式了;如果研究微電子技術(shù),那么滿篇都是集成電路圖了。