摘要:該文深入研究了用例模型中用例之間的關(guān)系:包含、擴(kuò)展、泛化。從事件流的細(xì)節(jié)剖析了用例關(guān)系的執(zhí)行過程,顯示了他們的本質(zhì)特征。給出了具體的描述方式。并給出了具體的實(shí)例。
關(guān)鍵詞:UML建模;用例模型;用例間關(guān)系
中文分類號:TP309 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2009)35-9988-03
Research on Relationship among the Use Cases in UML
ZOU Ping-xiang
(Xinshao County, Hunan Province industrial vocational school,Xinshao 422900,Hunan)
Abstract: In this paper, we research the relationship of use case in model of use case: include, extension, generalization. Analyze the execution of a process from event flow. Show their character in essence. Give some description on relationship of use case, and list some concrete instance.
Key words: modeling of UML; model of the use case; relation of the use case
通常我們構(gòu)建用例模型有三個(gè)主要的原因: 1) 使用例(use case)更易于理解。2) 將在許多用例內(nèi)說明的公有行為分離出來。3) 使用例模型更易于維護(hù)。 基于以上的需求,我們有三種關(guān)系(包含、擴(kuò)展、繼承)可以用于構(gòu)建用例??梢杂眠@些關(guān)系來分析出用例部件,這些部件可以在其他用例中復(fù)用,也可以作為該用例的特例或選項(xiàng)。
1)如果基本用例中有一部分功能,該基本用例的執(zhí)行與否由這部分功能的結(jié)果唯一決定,而不是由產(chǎn)生該結(jié)果的方法來決定,則可以將這一部分功能分離出來,放到一個(gè)包含用例中。采用包含關(guān)系,可以將包含用例顯式的插入基本用例中。
2)如果基本用例的一部分是可選的,或?qū)τ诶斫庠摶居美闹饕康膩碚f不是必需的,那么可以將這部分功能分離出來,形成一個(gè)擴(kuò)展用例,以簡化基本用例的結(jié)構(gòu)。利用擴(kuò)展關(guān)系,可以將擴(kuò)展用例隱式的插入基本用例中。
3)如果用例在行為和結(jié)構(gòu)上具有共同點(diǎn)而且在目的上又很相似,則可以將它們的共同部分分離出來,形成一個(gè)父用例(基本用例)。而子用例可以繼承該父用例。子用例可以在從父用例繼承的結(jié)構(gòu)中插入新的行為或修改現(xiàn)有的行為。
1 包含關(guān)系
包含關(guān)系是從基本用例到包含用例的關(guān)系,它指定如何將為包含用例定義的行為明確地插入到為基本用例定義的行為中。
1.1 解釋
基本用例通過包含關(guān)系連接到包含用例,包含用例總是抽象的。它描述在執(zhí)行基本用例的用例實(shí)例中插入的行為段。基本用例可控制與包含用例的關(guān)系,并可依賴于執(zhí)行包含用例所得的結(jié)果,但基本用例和包含用例都不能訪問對方的屬性。從這種意義上講,包含用例是被封裝的,它代表可在各種不同基本用例中復(fù)用的行為。[1]我們可以將包含關(guān)系用于:
1)從基本用例中分解出這樣的行為:它對于了解基本用例的主要目的并不是必需的,只有它的結(jié)果才比較重要。
2)分解出兩個(gè)或更多用例所共有的行為。 [2]
一個(gè)基本用例可以有多個(gè)包含用例。一個(gè)包含用例可以包含在若干基本用例中。這并不表示這些基本用例之間存在任何關(guān)系。甚至同一個(gè)包含用例和同一個(gè)基本用例之間可以有多個(gè)包含關(guān)系,前提是包含用例必須在基本用例中的不同位置插入,而包含關(guān)系就定義了插入的位置。添加的所有用例都可以是嵌套的,這意味著一個(gè)包含用例可以用作另一個(gè)包含用例的基本用例。由于包含用例是抽象的,因此它不需要有與它相關(guān)的主角。只有當(dāng)包含用例中的行為明確地涉及到與主角的交互時(shí),才需要與主角的通信關(guān)聯(lián)關(guān)系。
1.2 執(zhí)行包含
包含用例的行為插入到基本用例中的一個(gè)位置。當(dāng)遵循基本用例說明的用例實(shí)例到達(dá)基本用例中定義了包含關(guān)系的位置,它就將改而遵循包含用例的說明。一旦執(zhí)行完包含用例,用例實(shí)例就將在基本用例中它先前停止的地方重新開始。[1]包含關(guān)系是無條件的:如果用例實(shí)例到達(dá)基本用例中定義了包含關(guān)系的位置,就總會執(zhí)行包含。如果要表達(dá)條件,就需要將其作為基本用例的一部分來表達(dá)。如果用例實(shí)例無論如何也不能到達(dá)定義了包含關(guān)系的位置,則不會執(zhí)行包含。
包含用例是一個(gè)連續(xù)的行為段,所有這些行為都包含在基本用例的一個(gè)位置中。如果我們需要將一些行為段分別插入不同位置,就應(yīng)考慮使用擴(kuò)展關(guān)系或用例泛化關(guān)系。
1.3 描述包含關(guān)系
對于包含關(guān)系,我們應(yīng)在基本用例的行為序列中定義要插入包含用例的位置。要定義該位置,可以引用基本用例事件流中的特定步驟或分支流。為清晰起見,還應(yīng)在描述基本用例事件流文本中提及包含用例。
2 擴(kuò)展關(guān)系
擴(kuò)展關(guān)系是從擴(kuò)展用例到基本用例的關(guān)系,它說明為擴(kuò)展用例定義的行為如何插入到為基本用例定義的行為中。它是以隱含形式插入的,也就是說,擴(kuò)展用例并不在基本用例中顯示。
2.1 解釋
擴(kuò)展關(guān)系將擴(kuò)展用例與基本用例連接了起來。通過在基本用例中引用擴(kuò)展點(diǎn),可以定義在基本用例的哪些位置插入擴(kuò)展用例。擴(kuò)展用例通常是抽象的,但并不必須如此。[2]我們可以出于以下幾個(gè)目的使用擴(kuò)展用例:
1) 表明用例的某一部分是可選(或可能可選)的系統(tǒng)行為。這樣,我們就可以將模型中的可選行為和必選行為分開。
2) 表明只在特定條件(有時(shí)是例外條件)下才執(zhí)行分支流,如觸發(fā)警報(bào)。
3) 表明可能有一組行為段,其中的一個(gè)或多個(gè)段可以在基本用例中的擴(kuò)展點(diǎn)處插入。所插入的行為段(以及插入的順序)將取決于在執(zhí)行基本用例時(shí)與主角進(jìn)行的交互。
擴(kuò)展是有條件的,它是否執(zhí)行取決于在執(zhí)行基本用例時(shí)所發(fā)生的事件。基本用例并不控制執(zhí)行擴(kuò)展的條件:這些條件在擴(kuò)展關(guān)系中進(jìn)行說明。擴(kuò)展用例可以訪問和修改基本用例的屬性。但基本用例看不到擴(kuò)展用例,也無法訪問它們的屬性。[1]擴(kuò)展用例以隱含的方式修改基本用例。也就是說,基本用例定義了可以在其中添加擴(kuò)展用例的模塊化框架,但基本用例看不見特定的擴(kuò)展用例?;居美陨響?yīng)是完整的,即基本用例應(yīng)該是可理解且有意義的,而不必引用任何擴(kuò)展用例。但基本用例并不獨(dú)立于擴(kuò)展用例,因?yàn)槿绻麩o法遵循擴(kuò)展用例,就不能執(zhí)行基本用例。如果基本用例和“基本加擴(kuò)展”用例都必須是可以直接實(shí)例化的,或者如果我們希望通過添加來修改基本用例中的行為,則應(yīng)使用用例泛化關(guān)系。
擴(kuò)展用例可以包含一個(gè)或多個(gè)插入段,每個(gè)插入段都可以有內(nèi)置的備選路徑。這些插入段以遞增方式修改基本用例的行為。擴(kuò)展用例中的每個(gè)插入段可以插入到基本用例中的不同位置。這意味著擴(kuò)展關(guān)系包括一系列對擴(kuò)展點(diǎn)的引用,引用的數(shù)量與擴(kuò)展用例中插入段的數(shù)量相等。每個(gè)擴(kuò)展點(diǎn)都必須在基本用例中定義。
一個(gè)基本用例包含若干擴(kuò)展關(guān)系,這意味著一個(gè)用例實(shí)例在其生命期內(nèi)可以遵循多個(gè)擴(kuò)展用例。一個(gè)擴(kuò)展用例可以擴(kuò)展到幾個(gè)基本用例中,但這并不意味著這些基本用例之間存在依賴關(guān)系。同一個(gè)擴(kuò)展用例和同一個(gè)基本用例之間甚至可以有多個(gè)擴(kuò)展關(guān)系,前提是擴(kuò)展用例必須在基本用例的不同位置插入。這意味著不同的擴(kuò)展關(guān)系需要引用基本用例中的不同擴(kuò)展點(diǎn)。擴(kuò)展用例自身可以是擴(kuò)展、包含或泛化關(guān)系中的基本用例。例如,擴(kuò)展用例能夠以嵌套方式擴(kuò)展其他的擴(kuò)展用例。
2.2 執(zhí)行擴(kuò)展
當(dāng)執(zhí)行基本用例的用例實(shí)例達(dá)到基本用例中定義擴(kuò)展點(diǎn)的位置時(shí),將對相應(yīng)擴(kuò)展關(guān)系的條件進(jìn)行評估。如果條件成立,或者如果沒有條件,用例實(shí)例將遵循擴(kuò)展用例(或者擴(kuò)展用例中與擴(kuò)展點(diǎn)相對應(yīng)的插入段)。如果擴(kuò)展關(guān)系的條件不成立,就不執(zhí)行擴(kuò)展。就像所有用例一樣,擴(kuò)展用例可以有基本事件流和備選事件流。用例實(shí)例通過擴(kuò)展到底會采取哪條路徑,這不僅取決于在執(zhí)行之前發(fā)生的事件(用例實(shí)例的狀態(tài)),而且還取決于執(zhí)行擴(kuò)展時(shí)在與主角的交互中發(fā)生的事件。用例實(shí)例一旦執(zhí)行了擴(kuò)展,它就會在基本用例的中斷點(diǎn)處繼續(xù)執(zhí)行基本用例。(如圖3)
一個(gè)擴(kuò)展用例可以有多個(gè)插入段,每個(gè)插入段都與自己在基本用例中的擴(kuò)展點(diǎn)相關(guān)。在這種情況下,用例實(shí)例將繼續(xù)執(zhí)行基本用例,并持續(xù)到擴(kuò)展關(guān)系中指定的下一個(gè)擴(kuò)展點(diǎn)為止。在此點(diǎn)上,它將執(zhí)行擴(kuò)展用例的下一個(gè)插入段。這會重復(fù)進(jìn)行,直到執(zhí)行完最后一個(gè)插入段為止。請注意,只在第一個(gè)擴(kuò)展點(diǎn)對擴(kuò)展關(guān)系的條件進(jìn)行檢查;如果條件成立,用例實(shí)例就必須執(zhí)行所有插入段。(如圖4)
擴(kuò)展關(guān)系的多重性將約束整個(gè)擴(kuò)展用例可以重復(fù)發(fā)生的次數(shù)。注意,在這里所重復(fù)(并受多重性限制)的是整個(gè)擴(kuò)展用例,而不僅僅是一個(gè)插入段。
2.3 記錄擴(kuò)展關(guān)系
按照基本用例的屬性來說明擴(kuò)展的條件。另外,我們也可以選擇省略該條件,這時(shí)將總是執(zhí)行擴(kuò)展。每一擴(kuò)展關(guān)系都有一系列對基本用例中擴(kuò)展點(diǎn)(一個(gè)或多個(gè))的引用。擴(kuò)展點(diǎn)是按名稱引用的。如果擴(kuò)展用例具有多個(gè)插入段,就需要指定哪個(gè)段與哪個(gè)擴(kuò)展點(diǎn)相對應(yīng)。另外,還需要說明形成各個(gè)插入段的擴(kuò)展用例步驟或分支流。
示例:在電話系統(tǒng)中,可以由抽象的用例“顯示呼叫方身份”來擴(kuò)展用例“打電話”。這是一項(xiàng)可選服務(wù),通常稱為“呼叫方 ID”,接收方可能已請求該服務(wù),也可能還未請求。可能會如下說明從“顯示呼叫方身份”到“打電話”的擴(kuò)展關(guān)系:
條件:接收方必須已經(jīng)預(yù)定“呼叫方 ID”服務(wù)。
擴(kuò)展點(diǎn):顯示身份 - 插入整個(gè)用例。
我們可以向擴(kuò)展關(guān)系賦予多重性,如果省略多重性,則假定多重性為一。
3 用例泛化關(guān)系
用例泛化關(guān)系指一種從子用例到父用例的關(guān)系,它指定了子用例如何特化父用例的所有行為和特征。
3.1 解釋
父用例可特化形成一個(gè)或多個(gè)子用例,子用例代表父用例比較特殊的形式。盡管在大多數(shù)情況下父用例是抽象的,但并不要求一定是抽象的。子用例繼承父用例的所有結(jié)構(gòu)、行為和關(guān)系。同一父用例的子用例都是該父用例的特例。這就是可適用于用例的泛化關(guān)系。[2]當(dāng)我們發(fā)現(xiàn)兩個(gè)或更多用例在行為、結(jié)構(gòu)和目的方面存在共性時(shí),就可以使用泛化關(guān)系。這時(shí),我們可以用一個(gè)新的、抽象的用例來描述這些共有部分,該用例隨后被子用例特化。 [3]
子用例依賴于父用例的結(jié)構(gòu)。子用例可以將附加行為添加到父用例中。雖然子用例可以從父用例繼承行為段,但是必須慎重修改,以便保持父用例的使用目的。父用例的結(jié)構(gòu)由子用例保持。這意味著盡管所有行為段(即父用例事件流的步驟或分支流)仍然必須存在,但是這些行為段的內(nèi)容可以被子用例修改。
如果父用例為抽象用例,則它可以具有不完整的行為段。但是,子用例必須補(bǔ)充完善這些行為段,并使得它們對于主角而言是有意義的。如果父用例是一個(gè)抽象用例,則它無需與主角發(fā)生關(guān)系。如果兩個(gè)子用例都對同一父用例(或基本用例)進(jìn)行特化,則二者之間的特化是相互獨(dú)立的,這意味著它們可以在各自獨(dú)立的用例實(shí)例中執(zhí)行。這與包含關(guān)系和擴(kuò)展關(guān)系不同。在包含和擴(kuò)展關(guān)系中,一些附加用例隱式或顯式地修改了執(zhí)行相同基本用例的一個(gè)用例實(shí)例。
用例的泛化關(guān)系和包含關(guān)系都可以用來復(fù)用該模型用例間的行為。二者的區(qū)別是,在用例泛化關(guān)系中,執(zhí)行子用例不受父用例的結(jié)構(gòu)和行為(復(fù)用部分)的影響;而在包含關(guān)系內(nèi),執(zhí)行基本用例只依賴包含用例(復(fù)用部分)執(zhí)行有關(guān)功能的結(jié)果。另一個(gè)區(qū)別是,在泛化關(guān)系中,子用例有相似的目的和結(jié)構(gòu);而在包含關(guān)系中,復(fù)用相同包含用例的基本用例在目的上可以完全不同,但是它們需要執(zhí)行相同的功能。
3.2 執(zhí)行用例泛化關(guān)系
執(zhí)行子用例的用例實(shí)例將遵循父用例事件流,同時(shí)插入附加行為或修改在子用例事件流中定義的行為。
3.3 描述用例泛化關(guān)系
通常,可以不用描述泛化關(guān)系本身。相反,在子用例事件流中,我們必須指定如何將新步驟插入到繼承行為中以及怎樣去修改繼承行為。如果子用例特化了不止一個(gè)父用例(多繼承),則必須在子用例的規(guī)約中明確說明父用例的行為序列如何在子用例中交替執(zhí)行。
4 總結(jié)
運(yùn)用用例的三中關(guān)系(包含、擴(kuò)展、泛化)可以充分的描述用戶的需求以及需求之間的關(guān)系。但要注意應(yīng)當(dāng)與客戶和用戶不斷地深入討論如何合并包含、擴(kuò)展和泛化關(guān)系,并確信他們對產(chǎn)生的用例和主角有清楚的理解和認(rèn)識,并且對有關(guān)說明形成一致意見。這樣捕獲的需求才是真正用戶需要的需求。
參考文獻(xiàn):
[1] Grady B.UML用戶指南[M].北京:機(jī)械工業(yè)出版社,2008.
[2] 蔣惠.UML設(shè)計(jì)核心技術(shù)[M].北京:北京希望電子出版社,2007.
[3] Meilir J.UML面向?qū)ο笤O(shè)計(jì)基礎(chǔ)[M].北京:人民郵電出版社,2007.
[4] James R.UML參考手冊[M].北京:機(jī)械工業(yè)出版社,2006.