簡介
下圖顯示了回收機系統用例模型的一部分:用例圖,顯示包含主角和用例的用例模型示例。系統建模有許多種方法,每種建模方法可以滿足不同的目的。然而,用例模型最重要的作用是將系統行為傳達給客戶或最終用戶。因此,模型必須易於理解。
可能與該系統互動的用戶和任何其他系統都是主角。由於主角代表了系統用戶,它們協助界定系統並提供十分明確的系統用途說明。編寫用例依據主角的需求來進行。這樣就確保該系統成為用戶期望得到的系統。
套用
如何演進
主角和用例都是通過將客戶需求及潛在用戶當作重要的信息查找到的。找到這些用例和主角後,應對它們作簡要說明。在詳細說明這些用例之前,客戶應複審該用例模型以核實所有的用例和主角都已經找到,並且它們可以提供客戶所需要的東西。
在疊代開發環境中,您可以選擇用例的子集以便在每個疊代中詳細描述。另請參見活動:確定用例的優先權。主角和用例找到後,需要詳細說明每個用例的事件流。這些說明指出系統與主角互動的方式以及在各個獨立用例中系統執行的有關操作。最後,對已完成的用例模型(包括用例說明)進行複審,開發人員和客戶使用該模型對系統應執行的操作達成一致意見。
避免功能分解
用例模型退化導致系統功能分解的情況並不罕見。為避免發生這種情況,必須注意以下故障現象:
“小”用例,即對事件流的說明只有一個或少數幾個句子。
“許多”用例,即用例的數量有好幾百,而不是好幾十。
用例名的構造類似於“根據這一特定數據執行本操作”或“利用這一數據執行本功能”等。例如,“在 ATM 機上輸入個人識別號”不應建模為 ATM 機的一個單獨用例,原因是沒有人會使用系統僅執行這一操作。用例是一個完整事件流,它可以產生對主角有價值的東西。
為避免功能分解,您需要確保該用例模型有助於回答諸如以下的問題:
系統的環境是什麼?
為什麼要建立系統?
用戶在使用系統時希望獲得什麼?
系統將給用戶創造什麼價值?
非功能性需求
不難發現,用例是一個很好的獲取系統功能性需求的方法。但是對於非功能性需求,情況又如何呢?什麼是非功能性需求,可以在何處獲得它們?非功能性需求通常分為可用性需求、可靠性需求、性能需求以及可替換性需求(另請參閱概念:需求)。它們通常是指定需要符合任意法律法規要求的需求。它們也可以是由於所使用的作業系統、環境平台、兼容性或所採用的任何套用標準等問題產生的設計約束。通常,任何不允許有一個以上設計選項的需求都可以認為是一個設計約束。許多非功能性需求適用於一個單獨的用例,並且可以在該用例的特徵內獲得這些需求。在這種情況下,這些需求可以在用例的事件流內獲取,或者作為用例的一個特殊需求來獲取(請參閱指南:用例)。
示例在回收機系統中,返還儲存項用例的一個特定非功能性需求是:
該機器識別儲存項的可靠性必須高於 95%。
通常,功能性需求適用於整個系統。此類需求可以在補充規約中獲得(請參閱工件:補充規約)。 示例:
在回收機系統中,一個適用於整個系統的非功能性規約是:
機器每次只允許一個用戶使用。
兩難局面
學習如何確定用例應該在哪個明細級別上“開始和結束”是一件比較困難的事情。特徵和用例開始於何處,而用例結束和設計開始又在什麼地方?我們通常說,用例或軟體需求應該規定系統做“什麼”而不是“如何”做的問題。以下圖為例:一個人的終點是另一個人的起點。根據個人背景,您可以使用不同的環境來確定您對“什麼”以及“如何”的理解。當決定是否應該將某個細節擯棄於用例模型之外時,需要仔細考慮這一問題。
具體用例和抽象用例
具體用例和抽象用例之間存在一個區別。具體用例由主角來啟動,並且構成一個完整的事件流。“完整”意味著該用例的一個實例執行由主角調用的全部操作。
抽象用例本身從來不會被實例化。抽象用例包括在(請參閱指南:包含關係)其他用例中,擴展到(請參閱指南:擴展關係)或泛化關係(請參閱指南:用例泛化關係)其他用例。在啟動一個具體用例時,也就創建了該用例的一個實例。這一實例還展示了由其關聯關係的抽象用例指定的活動。因而,從抽象用例中無法創建單獨的實例。
由於主角在系統中“看見”和啟動的是具體用例,因此這兩種用例之間的區別非常重要。
表明一個用例為抽象用例時,可以將其名稱格式設定為斜體。
示例:創建任務用例包括在“註冊單”用例中“創建任務”用例是一個抽象用例。在庫房管理系統中,“創建任務”抽象用例包括在“註冊單”用例中。啟動“註冊單”用例後,將創建一個註冊單實例。該實例除了遵循註冊單的事件流之外,它還遵循在所包含的用例“創建任務”內說明的事件流。“創建任務”本身從來不被執行,但始終作為“註冊單”(或其他任何包含“創建任務”的用例)的一個部分。因此,“創建任務”是一個抽象用例。
構建
構建用例模型有三個主要的原因:使用例更易於理解。
將在許多用例內說明的公有行為分離出來。
使用例模型更易於維護。
然而,構建模型並不是首先要做的事情。在您對用例的行為有更深入的了解(而不是一句話簡要說明)之前,千萬不要構建該用例。您至少需要為該用例的事件流建立一個分步說明大綱,確保您的決策是建立在對該行為有精確而充分的理解基礎之上。
有三種關係可以用於構建用例。您可以使用這些關係來分析出用例部件,這些部件可以在其他用例中復用,或者作為該用例的特例或選項。表示修改的用例稱為附加用例。被修改的用例稱為基本用例。
如果基本用例中有一部分功能,該用例的執行與否由它的結果唯一決定,而不是由產生該結果的方法來決定,則可以將這一部分功能分離出來,放到一個附加用例中。採用包含關係,可以將附加用例顯式插入基本用例中。另請參見指南:包含關係。
如果基本用例的一部分是可選的,或對於理解該用例的主要目的來說不是必需的,那么您可以將這部分分離出來,形成一個附加用例,以簡化基本用例的結構。利用擴展關係,可以將附加用例隱式插入基本用例中。另請參見指南:擴展關係。
如果用例在行為和結構上具有共同點而且在目的上又很相似,則可以將它們的共同部分分離出來,形成一個基本用例(父用例)。而附加用例(子用例)可以繼承該父用例。子用例可以在從父用例繼承的結構中插入新的行為或修改現有的行為。另請參見指南:用例泛化關係。
您可以使用主角泛化關係來顯示主角之間的特化情況。另請參見指南:主角泛化關係。
示例:以訂單管理系統的用例模型部分為例進行說明。由於他們具有略微不同的特徵,因此將普通客戶從 Internet 客戶中分離開來是非常有用的。然而,因為 Internet 客戶的確顯示了一個客戶具有的所有特徵,所以您可以說 Internet 客戶是客戶的一個特例,並且能夠通過主角泛化關係來指示。在本圖中,具體用例分別是“電話訂購”(由客戶主角發出)和“Internet 訂購”(由 Internet 客戶發出)。這些用例都是更普通的“一個抽象用例。“請求目錄”用例代表一個可選行為段,它不是“訂購”用例主要目標的組成部分。它已經被分離出來,形成了一個抽象用例,用於簡化“訂購”用例。“提供客戶數據”用例是一個已分離出的行為段。它之所以被分離出來,是因為它是一個獨立功能,只有它的結果才能影響“訂購”用例。“供給客戶數據”用例還可以在其他用例中復用。“請求目錄”用例和“供給客戶數據”用例在本示例中都屬於抽象用例。
本用例圖顯示訂單管理系統的用戶模型部分。
下表顯示了三個不同用例關係之間更詳細的比較:
為達到更易於理解的目的,組織用例模型的另一個方法是對用例進行分組,形成多個包。用例模型可以組織為一個有層次的用例包結構,而主角或用例是該結構中的“樹葉”。另請參見指南:用例包。
和主角相關性
每個用例的執行都包含與一個或多個主角的交流。用例實例始終通過主角要求系統執行某些任務來啟動。這意味著每個用例需要與主角建立通信關聯關係。此規則的理由是強迫系統只提供用戶需要的功能,而不提供任何其他的東西。如果存在無人請求的用例,則表明在該用例模型或需求中存在錯誤。
然而,此規則也有一些例外情況:
如果用例是抽象的(不是可獨立實例化的),則其行為可能不包括與主角的互動。這種情況下,將不存在任何從該抽象用例到主角的通信關聯關係。
如果父用例說明了所有的主角通信,則泛化關係中的子用例不需要與主角相關聯。
調查說明
用例模型的調查說明應該:聲明哪些是系統的主要用例(系統建立的原因)。
總結有關係統的重要技術實際情況。
指出系統定界-系統將不執行的操作。
概述系統的環境,例如目標平台和現有的軟體。
描述在該系統中正常執行用例的任意序列。
詳細說明用例模型未處理的功能。
示例:以下是關於回收機的用例模型的調查說明示例:
本模型包括三個主角和三個用例。主要用例是“回收項”,它說明回收機的主要用途。
支持用例有:“列印日常報告”,操作員可以使用它獲得關於已經回收多少項目的報告。
“管理儲存項”,操作人員可以使用它來變更某個儲存項類型的退款金額,或增加新的儲存項類型。