用例(Use Case)是一種描述系統(tǒng)需求的方法,使用用例的方法來描述系統(tǒng)需求的過程就是用例建模。用例方法最早是由Iva Jackboson博士提出的,后來被綜合到UML規(guī)范之中,成為一種標準化的需求表述體系。用例的使用在RUP中被推崇備至,整個RUP流程都被稱作是"用例驅(qū)動"(Use-Case Driven)的,各種類型的開發(fā)活動包括項目管理、分析設(shè)計、測試、實現(xiàn)等都是以系統(tǒng)用例為主要輸入工件,用例模型奠定了整個系統(tǒng)軟件開發(fā)的基礎(chǔ)。
1. 什么是用例?
在介始用例方法之前,我們首先來看一下傳統(tǒng)的需求表述方式-"軟件需求規(guī)約"(Software Requirement Specification)。傳統(tǒng)的軟件需求規(guī)約基本上采用的是功能分解的方式來描述系統(tǒng)功能,在這種表述方式中,系統(tǒng)功能被分解到各個系統(tǒng)功能模塊中,我們通過描述細分的系統(tǒng)模塊的功能來達到描述整個系統(tǒng)功能的目的。
采用這種方法來描述系統(tǒng)需求,非常容易混淆需求和設(shè)計的界限,這樣的表述實際上已經(jīng)包含了部分的設(shè)計在內(nèi)。由此常常導(dǎo)致這樣的迷惑:系統(tǒng)需求應(yīng)該詳細到何種程度?一個極端就是需求可以詳細到概要設(shè)計,因為這樣的需求表述既包含了外部需求也包含了內(nèi)部設(shè)計。在有些公司的開發(fā)流程中,這種需求被稱為"內(nèi)部需求",而對應(yīng)于用戶的原始要求則被稱之為"外部需求"。
功能分解方法的另一個缺點是這種方法分割了各項系統(tǒng)功能的應(yīng)用環(huán)境,從各項功能項入手,你很難了解到這些功能項是如何相互關(guān)聯(lián)來實現(xiàn)一個完成的系統(tǒng)服務(wù)的。所以在傳統(tǒng)的SRS文檔中,我們往往需要另外一些章節(jié)來描述系統(tǒng)的整體結(jié)構(gòu)及各部分之間的相互關(guān)聯(lián),這些內(nèi)容使得SRS需求更象是一個設(shè)計文檔。
1.1 參與者和用例
從用戶的角度來看,他們并不想了解系統(tǒng)的內(nèi)部結(jié)構(gòu)和設(shè)計,他們所關(guān)心的是系統(tǒng)所能提供的服務(wù),也就是被開發(fā)出來的系統(tǒng)將是如何被使用的,這就用例方法的基本思想。用例模型主要由以下模型元素構(gòu)成:
參與者(Actor)
參與者是指存在于被定義系統(tǒng)外部并與該系統(tǒng)發(fā)生交互的人或其他系統(tǒng),他們代表的是系統(tǒng)的使用者或使用環(huán)境。
用例(Use Case)
用例用于表示系統(tǒng)所提供的服務(wù),它定義了系統(tǒng)是如何被參與者所使用的,它描述的是參與者為了使用系統(tǒng)所提供的某一完整功能而與系統(tǒng)之間發(fā)生的一段對話。
通訊關(guān)聯(lián)(Communication Association)
通訊關(guān)聯(lián)用于表示參與者和用例之間的對應(yīng)關(guān)系,它表示參與者使用了系統(tǒng)中的哪些服務(wù)(用例),或者說系統(tǒng)所提供的服務(wù)(用例)是被哪些參與者所使用的。
這大三種模型元素在UML中的表述如下圖所示。
以銀行自動提款機(ATM)為例,它的主要功能可以由下面的用例圖來表示。ATM的主要使用者是銀行客戶,客戶主要使用自動提款機來進行銀行帳戶的查詢、提款和轉(zhuǎn)帳交易。
通訊關(guān)聯(lián)表示的是參與者和用例之間的關(guān)系,箭頭表示在這一關(guān)系中哪一方是對話的主動發(fā)起者,箭頭所指方是對話的被動接受者;如果你不想強調(diào)對話中的主動與被動關(guān)系,可以使用不帶箭頭的關(guān)聯(lián)實線。在參與者和用例之間的信息流不是由通訊關(guān)聯(lián)來表示的,該信息流是缺省存在的(用例本身描述的就是參與者和系統(tǒng)之間的對話),并且信息流向是雙向的,它與通訊關(guān)聯(lián)箭頭所指的方向亳無關(guān)系。
1.2 用例的內(nèi)容
用例圖使我們對系統(tǒng)的功能有了一個整體的認知,我們可以知道有哪些參與者會與系統(tǒng)發(fā)生交互,每一個參與者需要系統(tǒng)為它提供什么樣的服務(wù)。用例描述的是參與者與系統(tǒng)之間的對話,但是這個對話的細節(jié)并沒有在用例圖中表述出來,針對每一個用例我們可以用事件流來描述這一對話的細節(jié)內(nèi)容。如在ATM系統(tǒng)中的"提款"用例可以用事件流表述如下:
提款-基本事件流
1. 用戶插入信用卡
2. 輸入密碼
3. 輸入提款金額
4. 提取現(xiàn)金
5. 退出系統(tǒng),取回信用卡
但是這只描述了提款用例中最順利的一種情況,作為一個實用的系統(tǒng),我們還必須考慮可能發(fā)生的各種其他情況,如信用卡無效、輸入密碼錯、用戶帳號中的現(xiàn)金余額不夠等,所有這些可能發(fā)生的各種情況(包括正常的和異常的)被稱之為用例的場景(Scenario),場景也被稱作是用例的實例(Instance)。在用例的各種場景中,最常見的場景是用基本流(Basic Flow)來描述的,其他的場景則是用備選流(Alternative Flow)來描述。對于ATM系統(tǒng)中的"提款"用例,我們可以得到如下一些備選流:
提款-備選事件流
備選流一:用戶可以在基本流中的任何一步選擇退出,轉(zhuǎn)至基本流步驟5。
備選流二:在基本流步驟1中,用戶插入無效信用卡,系統(tǒng)顯示錯誤并退出信用卡,用例結(jié)束。
備選流三:在基本流步驟2中,用戶輸入錯誤密碼,系統(tǒng)顯示錯誤并提示用戶重新輸入密碼,重新回到基本流步驟2;三次輸入密碼錯誤后,信用卡被系統(tǒng)沒收,用例結(jié)束。
…
通過基本流與備選流的組合,就可以將用例所有可能發(fā)生的各種場景全部描述清楚。我們在描述用例的事件流的時候,就是要盡可能地將所有可能的場景都描述出來,以保證需求的完備性。
1.3 用例方法的優(yōu)點
用例方法完全是站在用戶的角度上(從系統(tǒng)的外部)來描述系統(tǒng)的功能的。在用例方法中,我們把被定義系統(tǒng)看作是一個黑箱,我們并不關(guān)心系統(tǒng)內(nèi)部是如何完成它所提供的功能的。用例方法首先描述了被定義系統(tǒng)有哪些外部使用者(抽象成為Actor),這些使用者與被定義系統(tǒng)發(fā)生交互;針對每一參與者,用例方法又描述了系統(tǒng)為這些參與者提供了什么樣的服務(wù)(抽象成為Use Case),或者說系統(tǒng)是如何被這些參與者使用的。所以從用例圖中,我們可以得到對于被定義系統(tǒng)的一個總體印象。
1. 什么是用例?
在介始用例方法之前,我們首先來看一下傳統(tǒng)的需求表述方式-"軟件需求規(guī)約"(Software Requirement Specification)。傳統(tǒng)的軟件需求規(guī)約基本上采用的是功能分解的方式來描述系統(tǒng)功能,在這種表述方式中,系統(tǒng)功能被分解到各個系統(tǒng)功能模塊中,我們通過描述細分的系統(tǒng)模塊的功能來達到描述整個系統(tǒng)功能的目的。
采用這種方法來描述系統(tǒng)需求,非常容易混淆需求和設(shè)計的界限,這樣的表述實際上已經(jīng)包含了部分的設(shè)計在內(nèi)。由此常常導(dǎo)致這樣的迷惑:系統(tǒng)需求應(yīng)該詳細到何種程度?一個極端就是需求可以詳細到概要設(shè)計,因為這樣的需求表述既包含了外部需求也包含了內(nèi)部設(shè)計。在有些公司的開發(fā)流程中,這種需求被稱為"內(nèi)部需求",而對應(yīng)于用戶的原始要求則被稱之為"外部需求"。
功能分解方法的另一個缺點是這種方法分割了各項系統(tǒng)功能的應(yīng)用環(huán)境,從各項功能項入手,你很難了解到這些功能項是如何相互關(guān)聯(lián)來實現(xiàn)一個完成的系統(tǒng)服務(wù)的。所以在傳統(tǒng)的SRS文檔中,我們往往需要另外一些章節(jié)來描述系統(tǒng)的整體結(jié)構(gòu)及各部分之間的相互關(guān)聯(lián),這些內(nèi)容使得SRS需求更象是一個設(shè)計文檔。
1.1 參與者和用例
從用戶的角度來看,他們并不想了解系統(tǒng)的內(nèi)部結(jié)構(gòu)和設(shè)計,他們所關(guān)心的是系統(tǒng)所能提供的服務(wù),也就是被開發(fā)出來的系統(tǒng)將是如何被使用的,這就用例方法的基本思想。用例模型主要由以下模型元素構(gòu)成:
參與者(Actor)
參與者是指存在于被定義系統(tǒng)外部并與該系統(tǒng)發(fā)生交互的人或其他系統(tǒng),他們代表的是系統(tǒng)的使用者或使用環(huán)境。
用例(Use Case)
用例用于表示系統(tǒng)所提供的服務(wù),它定義了系統(tǒng)是如何被參與者所使用的,它描述的是參與者為了使用系統(tǒng)所提供的某一完整功能而與系統(tǒng)之間發(fā)生的一段對話。
通訊關(guān)聯(lián)(Communication Association)
通訊關(guān)聯(lián)用于表示參與者和用例之間的對應(yīng)關(guān)系,它表示參與者使用了系統(tǒng)中的哪些服務(wù)(用例),或者說系統(tǒng)所提供的服務(wù)(用例)是被哪些參與者所使用的。
這大三種模型元素在UML中的表述如下圖所示。
以銀行自動提款機(ATM)為例,它的主要功能可以由下面的用例圖來表示。ATM的主要使用者是銀行客戶,客戶主要使用自動提款機來進行銀行帳戶的查詢、提款和轉(zhuǎn)帳交易。
通訊關(guān)聯(lián)表示的是參與者和用例之間的關(guān)系,箭頭表示在這一關(guān)系中哪一方是對話的主動發(fā)起者,箭頭所指方是對話的被動接受者;如果你不想強調(diào)對話中的主動與被動關(guān)系,可以使用不帶箭頭的關(guān)聯(lián)實線。在參與者和用例之間的信息流不是由通訊關(guān)聯(lián)來表示的,該信息流是缺省存在的(用例本身描述的就是參與者和系統(tǒng)之間的對話),并且信息流向是雙向的,它與通訊關(guān)聯(lián)箭頭所指的方向亳無關(guān)系。
1.2 用例的內(nèi)容
用例圖使我們對系統(tǒng)的功能有了一個整體的認知,我們可以知道有哪些參與者會與系統(tǒng)發(fā)生交互,每一個參與者需要系統(tǒng)為它提供什么樣的服務(wù)。用例描述的是參與者與系統(tǒng)之間的對話,但是這個對話的細節(jié)并沒有在用例圖中表述出來,針對每一個用例我們可以用事件流來描述這一對話的細節(jié)內(nèi)容。如在ATM系統(tǒng)中的"提款"用例可以用事件流表述如下:
提款-基本事件流
1. 用戶插入信用卡
2. 輸入密碼
3. 輸入提款金額
4. 提取現(xiàn)金
5. 退出系統(tǒng),取回信用卡
但是這只描述了提款用例中最順利的一種情況,作為一個實用的系統(tǒng),我們還必須考慮可能發(fā)生的各種其他情況,如信用卡無效、輸入密碼錯、用戶帳號中的現(xiàn)金余額不夠等,所有這些可能發(fā)生的各種情況(包括正常的和異常的)被稱之為用例的場景(Scenario),場景也被稱作是用例的實例(Instance)。在用例的各種場景中,最常見的場景是用基本流(Basic Flow)來描述的,其他的場景則是用備選流(Alternative Flow)來描述。對于ATM系統(tǒng)中的"提款"用例,我們可以得到如下一些備選流:
提款-備選事件流
備選流一:用戶可以在基本流中的任何一步選擇退出,轉(zhuǎn)至基本流步驟5。
備選流二:在基本流步驟1中,用戶插入無效信用卡,系統(tǒng)顯示錯誤并退出信用卡,用例結(jié)束。
備選流三:在基本流步驟2中,用戶輸入錯誤密碼,系統(tǒng)顯示錯誤并提示用戶重新輸入密碼,重新回到基本流步驟2;三次輸入密碼錯誤后,信用卡被系統(tǒng)沒收,用例結(jié)束。
…
通過基本流與備選流的組合,就可以將用例所有可能發(fā)生的各種場景全部描述清楚。我們在描述用例的事件流的時候,就是要盡可能地將所有可能的場景都描述出來,以保證需求的完備性。
1.3 用例方法的優(yōu)點
用例方法完全是站在用戶的角度上(從系統(tǒng)的外部)來描述系統(tǒng)的功能的。在用例方法中,我們把被定義系統(tǒng)看作是一個黑箱,我們并不關(guān)心系統(tǒng)內(nèi)部是如何完成它所提供的功能的。用例方法首先描述了被定義系統(tǒng)有哪些外部使用者(抽象成為Actor),這些使用者與被定義系統(tǒng)發(fā)生交互;針對每一參與者,用例方法又描述了系統(tǒng)為這些參與者提供了什么樣的服務(wù)(抽象成為Use Case),或者說系統(tǒng)是如何被這些參與者使用的。所以從用例圖中,我們可以得到對于被定義系統(tǒng)的一個總體印象。

