《軟件工程》課件第9章_第1頁(yè)
《軟件工程》課件第9章_第2頁(yè)
《軟件工程》課件第9章_第3頁(yè)
《軟件工程》課件第9章_第4頁(yè)
《軟件工程》課件第9章_第5頁(yè)
已閱讀5頁(yè),還剩272頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第9章

面向?qū)ο蠓治?.1分析工作流9.2分析模型9.3確定分析包9.4提取實(shí)體類9.5提取邊界類和控制類9.6初始功能模型:考勤系統(tǒng)實(shí)例研究9.7分析類9.8初始類圖:考勤系統(tǒng)實(shí)例研究9.9描述分析對(duì)象間的交互9.10用例實(shí)現(xiàn):考勤系統(tǒng)實(shí)例研究9.11分析包9.12類圖遞增:考勤系統(tǒng)實(shí)例研究9.13測(cè)試流與分析工作流中的規(guī)格說明文檔9.14小結(jié)習(xí)題9

知識(shí)點(diǎn)

分析工作流,分析模型,功能模型,動(dòng)態(tài)模型,建模技術(shù)。

難點(diǎn)

如何將理論與實(shí)踐結(jié)合。

基于工作過程的教學(xué)任務(wù)

通過本章學(xué)習(xí),了解分析工作流;理解分析模型,學(xué)習(xí)建立分析包、分析類;通過電梯問題實(shí)例研究,學(xué)習(xí)實(shí)體類的提取,理解如何提取實(shí)體類;掌握分析工作流,學(xué)會(huì)如何描述分析對(duì)象間的交互,如何測(cè)試用例;規(guī)劃分析工作,進(jìn)行面向?qū)ο蠓治?;通過考勤系統(tǒng)實(shí)例研究,學(xué)習(xí)分析工作流,理解分析過程。

統(tǒng)一過程的分析工作流有兩個(gè)目的。從需求工作流的角度來(lái)看,分析工作流的目的是更深刻地理解需求;從設(shè)計(jì)工作流和實(shí)現(xiàn)工作流的角度看,分析工作流的目的是進(jìn)一步描述需求,使設(shè)計(jì)和實(shí)現(xiàn)更易于進(jìn)行。在分析階段,項(xiàng)目小組的成員共同努力,理解需求,建立分析模型。分析模型有助于精化需求,并探究系統(tǒng)的內(nèi)部,包括內(nèi)部的共享資源。而且,分析模型提供了更強(qiáng)的表達(dá)能力和形式化方法,例如交互圖,還有助于組織需求,并能提供一種可維護(hù)性的結(jié)構(gòu),便于應(yīng)對(duì)需求變更和重用。

9.1分

捕獲需求要使用客戶的語(yǔ)言,用例提供了這樣的基礎(chǔ)。但是,即使與客戶就系統(tǒng)功能達(dá)成了共識(shí),也很可能存在著尚未解決的需求問題。這是由于在捕獲需求過程中使用了直觀但不精確的客戶語(yǔ)言,要弄清楚可能遺漏哪些“未解決的問題”,再來(lái)了解一下與客戶有效交流的方法。

(1)用例必須盡量保持彼此獨(dú)立。這樣,就不會(huì)陷入到有關(guān)用例之間干擾、并發(fā)與沖突的細(xì)節(jié)中,在用例間競(jìng)爭(zhēng)系統(tǒng)內(nèi)部共享資源時(shí),經(jīng)常出現(xiàn)這類情況。例如,“存款”和“取款”用例要訪問同一儲(chǔ)戶的賬戶。當(dāng)一個(gè)參與者混合使用多個(gè)可能產(chǎn)生無(wú)法預(yù)測(cè)行為的用例時(shí),就可能產(chǎn)生沖突。例如,當(dāng)一個(gè)電話用戶使用“預(yù)置喚醒呼叫”用例后,接著使用“呼入改向”用例去對(duì)另一個(gè)電話用戶進(jìn)行電話喚醒呼叫。因此,在需求捕獲階段,用例之間的干擾、并發(fā)與沖突問題可能沒有得到完全解決。

(2)必須用客戶語(yǔ)言描述用例。這樣,在用例說明中就應(yīng)該主要使用自然語(yǔ)言,但是,僅使用自然語(yǔ)言會(huì)大大削弱表達(dá)能力。在需求捕獲階段,許多本來(lái)可以用更形式化的圖符來(lái)精確描述的細(xì)節(jié)問題,可能因此得不到解決,或只能模糊地描述。

(3)每個(gè)用例的構(gòu)造都是為了構(gòu)成完整且直觀的功能規(guī)格說明。這樣,就需要對(duì)用例進(jìn)行組織以便直觀地反映系統(tǒng)“真實(shí)”用例。例如,不能為了消除冗余而將用例設(shè)計(jì)得太小、太抽象或太不直觀,盡管能做到,還必須在用例說明的易理解性與可維護(hù)性之間進(jìn)行權(quán)衡。因此,需求間的冗余問題可能無(wú)法在需求捕獲期間解決。

由于存在著上述未解決的問題,分析的主要目的就是通過深入分析需求來(lái)使問題得以解決,與捕獲需求相比,最主要的差別在于可以用開發(fā)者的語(yǔ)言來(lái)描述。

因此,在分析階段更多地探究系統(tǒng)內(nèi)部,從而解決用例間的干擾以及類似的問題(上述第1條);還可以采用更形式化的語(yǔ)言對(duì)系統(tǒng)需求中的細(xì)節(jié)問題(上述第2條)進(jìn)行描述,以“精化需求”;另外,可以以易于理解、易于組織、易于修改、易于重用和易于維護(hù)的方式來(lái)組織需求(上述第3條)。這樣,可以按照不同的詳細(xì)程度跟蹤需求的不同描述,并保持彼此間的一致。實(shí)際上,在用例模型中的用例和分析模型中的用例實(shí)現(xiàn)之間可以互相跟蹤,兩類模型之間的區(qū)別如表9-1所示。

那么,為什么不在設(shè)計(jì)和實(shí)現(xiàn)系統(tǒng)的同時(shí)進(jìn)行需求分析呢?原因還在于:設(shè)計(jì)與實(shí)現(xiàn)遠(yuǎn)比分析(即精化和組織需求)復(fù)雜,需要分開來(lái)考慮。在設(shè)計(jì)與實(shí)現(xiàn)階段,必須構(gòu)造系統(tǒng)并確定其表現(xiàn)形式(包括構(gòu)架),必須對(duì)系統(tǒng)如何處理諸如性能和分布等需求做出決定,并回答諸如“如何優(yōu)化使執(zhí)行時(shí)間不超過5毫秒?”和“如何在網(wǎng)絡(luò)上部署代碼而不會(huì)加重網(wǎng)絡(luò)的通信負(fù)載?”等問題,還有很多其他類似的問題需要處理,例如,如何有效地利用數(shù)據(jù)庫(kù)和對(duì)象請(qǐng)求代理等已有的構(gòu)件,如何將這些構(gòu)件集成到系統(tǒng)構(gòu)架中,以及如何使用程序設(shè)計(jì)語(yǔ)言等,這里不一一列舉可能出現(xiàn)的問題。

最初的細(xì)化迭代重點(diǎn)在于分析,分析的焦點(diǎn)如圖8-5所示,有助于建立穩(wěn)定的構(gòu)架,有利于深入理解需求。之后,在細(xì)化階段的末期與構(gòu)造階段,構(gòu)架已經(jīng)穩(wěn)定而且需求明確后,重點(diǎn)便應(yīng)轉(zhuǎn)移到設(shè)計(jì)與實(shí)現(xiàn)上。

在分析階段,項(xiàng)目小組的成員共同努力,理解需求,建立分析模型,相關(guān)人員與結(jié)果如圖9-1所示。分析模型有助于精化需求,并探究系統(tǒng)的內(nèi)部結(jié)構(gòu),包括其內(nèi)部的共享資源。而且,分析模型提供了更強(qiáng)的表達(dá)能力和形式化方法,例如交互圖。分析模型還有助于組織需求,并提供一種可維護(hù)性的結(jié)構(gòu),例如具有對(duì)需求變化的柔性及重用,這種結(jié)構(gòu)不僅益于需求的維護(hù),而且還可以作為設(shè)計(jì)和實(shí)現(xiàn)活動(dòng)的輸入。但是,分析模型是一個(gè)抽象的過程,分析模型中提出的結(jié)構(gòu)不可能一直維持下去,需要在設(shè)計(jì)與實(shí)現(xiàn)期間對(duì)其進(jìn)行處理和折衷,因此,應(yīng)避免去解決某些問題和處理某些需求,最好是推遲到設(shè)計(jì)和實(shí)現(xiàn)階段去完成。

圖9-1分析中涉及的工作人員與制品

9.2分析模型

分析模型由代表該模型頂層包的分析系統(tǒng)組成;使用分析包將分析模型組織為更易于管理的若干部分,這些部分代表了對(duì)子系統(tǒng)或某一層系統(tǒng)的抽象;分析類代表了對(duì)系統(tǒng)設(shè)計(jì)中的類或子系統(tǒng)的抽象;在分析模型中,用例是通過分析類及其對(duì)象實(shí)現(xiàn)的,由分析模型中的各種協(xié)作來(lái)表示,標(biāo)記為用例實(shí)現(xiàn)—分析,如圖9-2所示。

統(tǒng)一過程是用例驅(qū)動(dòng)的。在分析工作流中,用類來(lái)描述用例。統(tǒng)一過程包含三種類型的類:實(shí)體類、邊界類和控制類。

實(shí)體類(EntityClass)用來(lái)對(duì)持久信息進(jìn)行建模。就銀行軟件產(chǎn)品來(lái)說,類Account是實(shí)體類,因?yàn)橘~戶信息必須保留在軟件產(chǎn)品中。

邊界類(BoundaryClass)用來(lái)對(duì)軟件產(chǎn)品和參與者之間的交互進(jìn)行建模。通常邊界類與輸入和輸出相關(guān)聯(lián),例如,在銀行軟件產(chǎn)品中,需要打印用戶賬單。

控制類(ControlClass)用來(lái)對(duì)復(fù)雜的計(jì)算和算法進(jìn)行建模。在銀行軟件產(chǎn)品中,計(jì)算利息的算法就是一個(gè)控制類。

三種類的UML符號(hào)構(gòu)造型(Stereotype)如圖9-3所示,是屬于UML的擴(kuò)展。

圖9-3表示實(shí)體類、邊界類和控制類的UML構(gòu)造型(UML擴(kuò)展機(jī)制)

下面,看一看分析工作流的活動(dòng),如圖9-4所示。

圖9-4分析工作流,包括參與的工作人員及其活動(dòng)

在分析期間,隨著分析模型的演化,構(gòu)架設(shè)計(jì)師不斷確定新的分析包、類和公共需求,而構(gòu)件工程師則負(fù)責(zé)對(duì)分析包進(jìn)行精化和維護(hù),如圖9-5所示。

圖9-5分析的輸入及結(jié)果

9.3確

分析包提供了將分析模型組織成更小、可管理的“塊”的方式,可以一開始就確定劃分分析任務(wù)的方法,或等到分析模型演化為一個(gè)需要分解的大型結(jié)構(gòu)時(shí)再來(lái)確定。

最初一般基于功能需求和問題域來(lái)確定分析包。因?yàn)橐獙⒐δ苄枨蟛东@為用例,所以確定分析包的簡(jiǎn)單方法是將一些主要的用例分配給一個(gè)具體包,然后在該包中實(shí)現(xiàn)相應(yīng)的功能。下面是將用例分配給具體包的原則。

需要支持具體業(yè)務(wù)過程的用例;

需要支持系統(tǒng)的具體參與者的用例;

通過泛化和擴(kuò)展關(guān)系建立用例的關(guān)聯(lián)。在用例彼此間具有特化或“擴(kuò)展”關(guān)系時(shí),用例集具有強(qiáng)內(nèi)聚性。

這樣,包會(huì)將變化局限于一個(gè)業(yè)務(wù)過程、一個(gè)參與者行為或一個(gè)緊密相關(guān)的用例集合中,在早期有助于將用例分配到包中。但是,用例一般不局限于一個(gè)包內(nèi),而是跨越幾個(gè)包。因此,隨著分析工作的進(jìn)行,當(dāng)用例實(shí)現(xiàn)為類(可能存在于不同的包中)之間協(xié)作時(shí),就會(huì)得到一個(gè)更加精化的包結(jié)構(gòu)。

舉例:確定分析包

在Interbank中,應(yīng)該如何從用例模型中確定分析包呢?用例“支付賬單”、“發(fā)送提醒通知單”和“給買主開單”都參與了同一個(gè)“銷售:從訂單到交貨”的業(yè)務(wù)過程。因此,可以將它們放到一個(gè)分析包中。但是,Interbank應(yīng)能針對(duì)不同客戶的需求提供不同的系統(tǒng)。有些客戶只作為買主使用系統(tǒng),另一些客戶只作為賣主,還有一些客戶既是買主又是賣主。

因此,采取將賣主需要的用例實(shí)現(xiàn)與買主需要的用例實(shí)現(xiàn)分開的措施,可以將業(yè)務(wù)過程“銷售:從訂單到交貨”作為一個(gè)分析包的設(shè)想進(jìn)行調(diào)整來(lái)滿足不同客戶的需要,這樣,根據(jù)客戶的需要可以分為兩個(gè)分析包:“買主賬單管理”和“賣主賬單管理”,如圖9-6所示。

注意,其他用例也支持業(yè)務(wù)過程“銷售:從訂單到交貨”,為了簡(jiǎn)化,這里忽略。

圖9-6從用例中確定分析包

9.3.1處理分析包之間的共性

在包間經(jīng)常會(huì)存在共性的內(nèi)容。例如,當(dāng)兩個(gè)或更多的分析包共享一個(gè)分析類時(shí)就會(huì)出現(xiàn),處理的方法是找出共享類,把它放到一個(gè)單獨(dú)的分析包中,或只是放到包的外面,然后讓包依賴這個(gè)通用的包或類。

這種共性的共享類很像實(shí)體類,可以跟蹤到領(lǐng)域或業(yè)務(wù)的實(shí)體類。因此,如果領(lǐng)域或業(yè)務(wù)的實(shí)體類是共享的,就值得研究,可以確定為通用分析包。

舉例:確定通用分析包

下面看看Interbank如何從領(lǐng)域模型中確定通用分析包。領(lǐng)域類“儲(chǔ)戶”和“賬戶”都表示現(xiàn)實(shí)世界中重要而復(fù)雜的實(shí)體,這些類需要復(fù)雜信息系統(tǒng)的支持,而且可以與其他更為具體的分析包共享。因而Interbank為每個(gè)類創(chuàng)建單獨(dú)的“賬戶管理”包和“儲(chǔ)戶管理”包,如圖9-7所示。

注意,“賬戶管理”包和“儲(chǔ)戶管理”包可能會(huì)包含很多分析類,例如分別與賬戶管理和儲(chǔ)戶管理有關(guān)的控制類和邊界類。所以,這些包不可能只包含一個(gè)或幾個(gè)可跟蹤到相應(yīng)領(lǐng)域的實(shí)體類。

圖9-7從領(lǐng)域類中確定通用分析包

9.3.2確定服務(wù)包

一般在分析工作的后期、對(duì)功能需求有了清晰的理解并且大多數(shù)分析類已經(jīng)存在的時(shí)候才確定服務(wù)包,同一服務(wù)包中的分析類用于相同的服務(wù)。

通常按下面的步驟來(lái)確定服務(wù)包。

為每個(gè)可選的服務(wù)確定一個(gè)服務(wù)包,這種服務(wù)包是一個(gè)定制的單元。

舉例:可選的服務(wù)包

大部分使用Interbank的賣主都希望系統(tǒng)具有發(fā)送提醒通知單的服務(wù),這種服務(wù)在可選的用例“發(fā)送提醒通知單”中描述。有些賣主希望一旦存在過期賬單就自動(dòng)發(fā)送提醒通知單,而另一些賣主希望在有過期賬單時(shí)先得到通知,而后再?zèng)Q定是否發(fā)送提醒通知單。這里,可以表示為兩種可選的且彼此專用的服務(wù)包:“自動(dòng)發(fā)送提醒通知”用于系統(tǒng)自動(dòng)發(fā)出提醒通知單,而“人工發(fā)送提醒通知”首先通知賣主,而后由他決定是否與買主聯(lián)系,如圖9-8所示。當(dāng)賣主不需要提醒通知支持時(shí),交付的系統(tǒng)中就不需要附帶該服務(wù)包,這些服務(wù)包包含在“賣主賬單管理”包中。

圖9-8“賣主賬單管理”包中的“自動(dòng)發(fā)送提醒通知”和“人工發(fā)送提醒通知”服務(wù)包

為每個(gè)可能成為可選的服務(wù)確定一個(gè)服務(wù)包,即使每個(gè)客戶都希望得到該服務(wù)。因?yàn)榉?wù)包中包含功能相關(guān)的類,所以會(huì)得到一種將大部分變化局限于個(gè)別服務(wù)包中的包結(jié)構(gòu)。這種準(zhǔn)則也可以描述為:為功能相關(guān)的類提供的每個(gè)服務(wù)確定一個(gè)服務(wù)包。例如,當(dāng)出現(xiàn)下述情況時(shí),類A和類B功能上是相關(guān)的。

①?A的變化很可能要求B有所變化;

②刪除A,B就是多余的;

③?A的對(duì)象可能通過幾個(gè)不同的消息與B的對(duì)象頻繁地交互。

舉例:確定封裝功能相關(guān)的類的服務(wù)包

“賬戶管理”包包括“賬戶”服務(wù)包,當(dāng)需要轉(zhuǎn)賬和提取事務(wù)歷史等活動(dòng)時(shí)可以訪問賬戶。包中還包括“風(fēng)險(xiǎn)管理”服務(wù)包,用于估計(jì)與某個(gè)特定賬戶相關(guān)的風(fēng)險(xiǎn)。這些不同的服務(wù)包是公共的,由幾個(gè)不同的用例實(shí)現(xiàn)使用,如圖9-9所示。

圖9-9“賬戶”服務(wù)包和“風(fēng)險(xiǎn)管理”服務(wù)包,每個(gè)服務(wù)包均封裝了功能相關(guān)的類

9.3.3確定分析包間的依賴

如果分析包的內(nèi)容間彼此關(guān)聯(lián),就應(yīng)該定義分析包間的依賴。其目標(biāo)是確定相對(duì)獨(dú)立、低耦合和高內(nèi)聚的包。高內(nèi)聚、低耦合使包更易于維護(hù),這是因?yàn)楦淖円粋€(gè)包中的某些類將主要影響該包中的類。例如,對(duì)以下各方面的限制或約束就是常見的特殊需求的例子。

持久性;

分布與并發(fā);

安全性;

容錯(cuò);

事務(wù)處理。

構(gòu)架設(shè)計(jì)師負(fù)責(zé)確定特殊需求,以便開發(fā)人員能夠使用它們來(lái)進(jìn)行特殊的處理。在某些情況下,特殊需求不能預(yù)先確定,只能在對(duì)用例實(shí)現(xiàn)和分析類進(jìn)行研究時(shí)才能確定。

為支持后續(xù)的設(shè)計(jì)和實(shí)現(xiàn),應(yīng)該確定每個(gè)特殊需求的關(guān)鍵特征。

舉例:確定特殊需求的關(guān)鍵特征

一個(gè)持久性需求具有以下特征:

大小范圍(SizeRange):保持持久性的對(duì)象的大小范圍。

容量(Volume):保持持久性的對(duì)象的數(shù)目。

持久性時(shí)間段(PersistencyPeriod):對(duì)象一般需要保持持久性的時(shí)間段。

更新頻率(UpdateFrequency):對(duì)象的更新頻率。

可靠性(Reliability):諸如對(duì)象在硬件或軟件崩潰時(shí)是

否能保存下來(lái)的可靠性問題。

因此,每個(gè)特殊需求的特征應(yīng)該針對(duì)引用特殊需求的類和用例實(shí)現(xiàn)來(lái)加以限定。

9.4提

實(shí)

9.4.1實(shí)體類的提取

實(shí)體類的提取包括三個(gè)迭代和增量執(zhí)行的步驟。

(1)功能建模(FunctionalModeling):給出所有用例的場(chǎng)景,場(chǎng)景是用例的實(shí)例。

(2)實(shí)體類建模(EntityClassModeling):也稱對(duì)象模型。確定實(shí)體類及其屬性,然后,確定實(shí)體類之間的聯(lián)系和交互行為,并用類圖表示這些信息。

(3)動(dòng)態(tài)建模(DynamicModeling):確定每個(gè)實(shí)體類執(zhí)行或?qū)ζ鋱?zhí)行的操作,用狀態(tài)圖、通信圖或順序圖表示這些行為。

像所有迭代增量過程一樣,這三個(gè)步驟不需要按順序執(zhí)行。一個(gè)模型的變化常常會(huì)引起其他兩個(gè)模型相應(yīng)的改變。

為了說明步驟是如何進(jìn)行的,下面提取經(jīng)典的電梯問題的實(shí)體類。

9.4.2面向?qū)ο蠓治觯弘娞輪栴}實(shí)例研究

電梯問題的邏輯原理是滿足以下約束條件在m層樓之間移動(dòng)n部電梯。

(1)每部電梯內(nèi)有m個(gè)按鈕,每個(gè)按鈕對(duì)應(yīng)一個(gè)樓層。當(dāng)有人按下按鈕時(shí),按鈕變亮并指示電梯到相應(yīng)的樓層;當(dāng)電梯到達(dá)相應(yīng)的樓層時(shí),按鈕變暗。

(2)除了一樓和頂樓外,每層樓有兩個(gè)按鈕,一個(gè)向上,一個(gè)向下。按鈕按下時(shí)變亮;當(dāng)電梯到達(dá)樓層并往請(qǐng)求方向移動(dòng)的時(shí)候,按鈕變暗。

(3)當(dāng)電梯沒有請(qǐng)求時(shí),停留在當(dāng)前樓層,電梯門關(guān)閉。

問題中有兩組按鈕。在n部電梯中,每部電梯內(nèi)有m個(gè)按鈕,每個(gè)按鈕對(duì)應(yīng)一層,稱之為電梯按鈕;而且,每個(gè)樓層有兩個(gè)按鈕,一個(gè)請(qǐng)求電梯向上,一個(gè)請(qǐng)求電梯向下,稱之為樓層按鈕;每個(gè)按鈕處于兩個(gè)狀態(tài):打開(按鈕變亮)或關(guān)閉(按鈕變暗)。最后,假設(shè)電梯門打開,超時(shí)后會(huì)自動(dòng)關(guān)閉。

下面對(duì)電梯問題進(jìn)行用例建模,如圖9-10所示。用戶和電梯之間的交互是,用戶按下電梯按鈕來(lái)命令電梯或用戶按下樓層按鈕來(lái)請(qǐng)求電梯停在某個(gè)樓層,所以有兩個(gè)用例:按電梯按鈕和按樓層按鈕。

圖9-10電梯問題案例研究用例圖

9.4.3功能建模:電梯問題實(shí)例研究

用例提供整體功能的一般描述,場(chǎng)景是用例的實(shí)例,就像對(duì)象是類的實(shí)例一樣。一般來(lái)說,場(chǎng)景有很多,每個(gè)場(chǎng)景代表一組特定的交互。

下面,考慮圖9-11的場(chǎng)景,這里包含了上面兩個(gè)用例的實(shí)例。

圖9-11一個(gè)正常場(chǎng)景的第一次迭代

圖9-11描述了一個(gè)正常場(chǎng)景,根據(jù)對(duì)電梯的理解,發(fā)生在用戶和電梯之間的正常的交互動(dòng)作。

圖9-11的場(chǎng)景是在仔細(xì)地觀察不同用戶與電梯之間的交互后,建立起來(lái)的,這需要了解業(yè)務(wù)。這19個(gè)事件詳細(xì)描述了用戶A和電梯系統(tǒng)的兩次交互(事件1和事件6),還有電梯系統(tǒng)各組件執(zhí)行的操作(事件2~5和事件7~19)。三個(gè)事件即“用戶A進(jìn)入電梯”、“用戶B離開電梯”和“用戶A離開電梯”沒有加標(biāo)號(hào)。這里只是注釋,因?yàn)?,在用戶A、用戶B進(jìn)入或離開電梯時(shí)沒有與電梯的任何組件發(fā)生交互。

下面,圖9-12描述了一個(gè)異常場(chǎng)景,當(dāng)用戶在3樓按下向上的按鈕,但他想去1樓時(shí),所發(fā)生的一類情況。該場(chǎng)景同樣是在觀察了很多電梯里用戶的行為構(gòu)造出來(lái)的,因?yàn)槭褂秒娞莸娜擞袝r(shí)候會(huì)按錯(cuò)按鈕。

圖9-11和圖9-12的場(chǎng)景,還有其他的場(chǎng)景,都是圖9-10用例的特定實(shí)例。OOA小組應(yīng)該研究足夠多的場(chǎng)景,對(duì)要建模的系統(tǒng)行為有一個(gè)全面的理解。這些信息會(huì)用于實(shí)體類建模,以確定實(shí)體類。

圖9-12一個(gè)異常場(chǎng)景

9.4.4實(shí)體類建模:電梯問題實(shí)例研究

下面就要提取實(shí)體類及其屬性,并用UML類圖表示,這里只確定實(shí)體類的屬性。

確定實(shí)體類的一種方法是從用例推導(dǎo)實(shí)體類,也就是說,開發(fā)人員仔細(xì)研究所有場(chǎng)景,包括正常的和異常的,以便找出在用例中起作用的組件。從圖9-11和圖9-12的場(chǎng)景可以看到,候選實(shí)體類是電梯按鈕、樓層按鈕、電梯、門和定時(shí)器等,這些候選實(shí)體類跟在實(shí)體類建模期間提取的實(shí)際的類是很接近的。一般來(lái)說,場(chǎng)景有很多,結(jié)果可能的類也很多,缺乏經(jīng)驗(yàn)的開發(fā)人員可能傾向于從場(chǎng)景中推導(dǎo)太多的類,這不利于實(shí)體類建模,因?yàn)閯h除一個(gè)多余的實(shí)體類要比添加一個(gè)新的實(shí)體類要困難得多。

另一種確定實(shí)體類的方法是使用CRC(ClassResponsibilityCollaboration,CRC)職責(zé)卡(類—責(zé)任—協(xié)作),當(dāng)開發(fā)人員具備特定領(lǐng)域?qū)I(yè)知識(shí)時(shí),該方法很有效。但是,如果開發(fā)人員在應(yīng)用領(lǐng)域沒有或只有很少經(jīng)驗(yàn),那么建議使用名詞提取的方法。

1.名詞提取

對(duì)于沒有領(lǐng)域?qū)I(yè)知識(shí)的開發(fā)人員,最好使用兩階段名詞提取法,先提取候選實(shí)體類,然后進(jìn)行篩選和細(xì)化。

階段1:用一段話描述軟件產(chǎn)品。

舉例:電梯問題描述

電梯里和樓層的按鈕控制一幢m層大樓里的n部電梯的移動(dòng)。當(dāng)按下請(qǐng)求電梯停在某一樓層的按鈕時(shí),按鈕變亮;當(dāng)滿足請(qǐng)求時(shí),按鈕變暗。當(dāng)一部電梯沒有請(qǐng)求時(shí),停留在當(dāng)前層,電梯門關(guān)閉。

階段2:識(shí)別名詞

先在上面的描述中識(shí)別出名詞,它們就是候選實(shí)體類。

舉例:電梯問題候選類

電梯里和樓層的按鈕控制一幢m層大樓里的n部電梯的移動(dòng)。當(dāng)按下請(qǐng)求電梯停在某一樓層的按鈕時(shí),按鈕變亮;當(dāng)滿足請(qǐng)求時(shí),按鈕變暗。當(dāng)一部電梯沒有請(qǐng)求時(shí),停留在當(dāng)前層,電梯門關(guān)閉。

有7個(gè)不同名詞:按鈕、電梯、樓層、移動(dòng)、大樓、請(qǐng)求和電梯門。其中3個(gè)名詞(樓層、大樓和電梯門)在問題邊界外,所以被剔除。剩下名詞中的2個(gè)(移動(dòng)和請(qǐng)求)是抽象名詞。經(jīng)驗(yàn)法則表明,抽象名詞很少是類,往往是類的屬性,例如,變亮是按鈕的屬性。因此剩下的兩個(gè)名詞則為候選實(shí)體類:電梯類(Elevator)和按鈕類(Button)。

結(jié)果如圖9-13所示。Button類有布爾類型屬性illuminated(變亮)對(duì)圖9-11和圖9-12場(chǎng)景中的事件2、7、9、11和16進(jìn)行建模。但是,這里有兩種類型的按鈕,所以Button類有兩個(gè)子類:ElevatorButton類和FloorButton類。ElevatorButton類和FloorButton類的每個(gè)實(shí)例與Elevator類的實(shí)例關(guān)聯(lián)。后者有布爾屬性doorOpen(電梯門打開)對(duì)兩個(gè)場(chǎng)景的事件4、8、12、14、17和19進(jìn)行建模。

圖9-13電梯問題案例研究類圖的第一次迭代

實(shí)際上,在電梯中,按鈕不直接與電梯發(fā)生作用。如果決定讓某部電梯響應(yīng)某個(gè)特定的請(qǐng)求,就需要電梯控制器。但是,問題描述中并沒有提到電梯控制器,所以在名詞提取過程中就沒有該實(shí)體類。換句話說,這里介紹的技術(shù)為找出候選實(shí)體類提供了一個(gè)思路,但肯定不能依賴它。

把ElevatorController類添加到圖9-13中,便產(chǎn)生了圖9-14。圖9-14中現(xiàn)在只有一對(duì)多關(guān)系,對(duì)其建模要比對(duì)圖9-13中的多對(duì)多關(guān)系建模要容易。在動(dòng)態(tài)建模之前,先了解另一種實(shí)體類建模技術(shù)。

2.CRC卡片—職責(zé)卡

類—責(zé)任—協(xié)作(CRC)卡片常應(yīng)用于分析工作流。對(duì)每個(gè)類,軟件開發(fā)小組填寫一張卡片,包括該類的名稱、功能(責(zé)任)和它調(diào)用的一組類以完成其功能(協(xié)作)。

圖9-14電梯問題案例研究類圖的第二次迭代

該方法有多種形式的應(yīng)用。首先,CRC卡片常包含類的屬性和方法,不是用自然語(yǔ)言所表達(dá)的“責(zé)任”。其次,該技術(shù)已經(jīng)發(fā)生變化,很多組織不再使用卡片,而是把類名寫在記事帖上,記事帖可以在白板上移動(dòng),用它們之間的連線表示協(xié)作關(guān)系?,F(xiàn)在,整個(gè)過程能夠自動(dòng)化進(jìn)行,諸如VisualParadigm等CASE工具就包含了在屏幕上生成和更新CRC卡片的組件。

CRC卡片的優(yōu)點(diǎn)在于:通過小組成員之間的交互可以發(fā)現(xiàn)類中遺漏的或錯(cuò)誤的字段,不管是屬性還是方法。此外,使用CRC卡片可以描述類之間的關(guān)系。一種做法是在小組成員間分發(fā)卡片,然后小組成員扮演類的責(zé)任。一個(gè)成員可能會(huì)說“我是Date類,我的責(zé)任是創(chuàng)建新的日期對(duì)象。”另一個(gè)小組成員可能會(huì)接著說,“我需要Date類的額外功能,需要把日期轉(zhuǎn)換為一個(gè)整數(shù),就是距離1900年1月1日的天數(shù),所以要得到兩個(gè)日期之間的天數(shù),然后把兩個(gè)對(duì)應(yīng)的整數(shù)相減?!币虼?,扮演CRC卡片的責(zé)任,是驗(yàn)證類圖是否完整和正確的有效手段之一。

如前所述,CRC卡片的不足之處在于:除非小組成員在應(yīng)用領(lǐng)域有豐富的經(jīng)驗(yàn),否則通常達(dá)不到識(shí)別實(shí)體類的目的。另一方面,一旦開發(fā)人員已經(jīng)確定了大多數(shù)的類,并知道了其責(zé)任和協(xié)作關(guān)系,那么CRC卡片是完成整個(gè)過程并確保其正確的好方法。

9.4.5動(dòng)態(tài)建模:電梯問題實(shí)例研究

動(dòng)態(tài)建模的目的是描述目標(biāo)產(chǎn)品的動(dòng)態(tài)行為,可以生成每個(gè)類的狀態(tài)圖或順序圖。首先,考慮ElevatorController類,為了簡(jiǎn)便起見,只考慮一部電梯。ElevatorController類的狀態(tài)圖如圖9-15所示。

圖9-15ElevatorController狀態(tài)圖的第一次迭代

狀態(tài)圖包含了狀態(tài)、事件和行為。類的屬性有時(shí)稱為狀態(tài)變量,在多數(shù)面向?qū)ο髮?shí)現(xiàn)中,產(chǎn)品狀態(tài)是由不同組件對(duì)象屬性的值決定的,一個(gè)事件的發(fā)生導(dǎo)致產(chǎn)品進(jìn)入其他狀態(tài)。

狀態(tài)、事件和行為分布在狀態(tài)圖中。例如,如果當(dāng)前狀態(tài)是ElevatorEventLoop并且事件“電梯停止,沒有待定請(qǐng)求”為真,則進(jìn)入圖9-15中的狀態(tài)GoingIntoWaitState。當(dāng)進(jìn)入狀態(tài)GoingIntoWaitState時(shí),執(zhí)行“在超時(shí)后關(guān)閉電梯門”操作。

考慮圖9-11場(chǎng)景的第一部分。事件1是“用戶A在2樓按下向上的樓層按鈕”?,F(xiàn)在來(lái)研究狀態(tài)圖。實(shí)心圓表示初始狀態(tài),該狀態(tài)將系統(tǒng)帶入狀態(tài)ElevatorEventLoop。沿著最左邊的垂線,如果按鈕按下時(shí)是不亮的,則系統(tǒng)進(jìn)入狀態(tài)ProcessingNewRequest,點(diǎn)亮按鈕并更新請(qǐng)求集,然后進(jìn)入狀態(tài)ElevatorEventLoop。

在圖9-11場(chǎng)景中的事件3是電梯到達(dá)3樓。回到狀態(tài)圖,考慮電梯接近3樓時(shí)將會(huì)發(fā)生什么。因?yàn)殡娞菔翘幵谶\(yùn)動(dòng)中的,所以,進(jìn)入狀態(tài)DeterminingIfStopRequested,執(zhí)行請(qǐng)求集檢查,因?yàn)橛脩鬉已經(jīng)請(qǐng)求電梯停在該樓,當(dāng)電梯到達(dá)時(shí),就進(jìn)入狀態(tài)StoppingAtFloor。電梯停在3樓,打開電梯門,啟動(dòng)定時(shí)器開始計(jì)時(shí)。去3樓的電梯按鈕沒有按下,接著,進(jìn)入狀態(tài)ElevatorEventLoop。

用戶A進(jìn)入電梯,按下去10樓的電梯按鈕。因此,進(jìn)入狀態(tài)ProcessingNewRequest,接著,又進(jìn)入狀態(tài)ElevatorEventLoop。此時(shí)電梯已經(jīng)停止,有兩個(gè)待定請(qǐng)求,所以下一個(gè)狀態(tài)是ClosingElevatorDoorss,電梯門在超時(shí)后關(guān)閉。3樓的樓層按鈕已由用戶A按下,所以接下來(lái)進(jìn)入的狀態(tài)是TurningOffFloorButton,關(guān)閉樓層按鈕。接著進(jìn)入狀態(tài)ProcessingNextRequest,電梯開始向4樓移動(dòng)。

在討論中,可以發(fā)現(xiàn),上面的狀態(tài)圖是從場(chǎng)景中構(gòu)造出來(lái)的,確切地說,場(chǎng)景中的特定事件一般化了。例如,考慮正常場(chǎng)景中的第一個(gè)事件“用戶A在3樓按下向上的樓層按鈕”。這個(gè)特定事件一般化為按下任意一個(gè)按鈕(樓層按鈕或電梯按鈕),這時(shí),有兩種可能,按鈕已經(jīng)是亮的(在這種情況下沒有什么事件發(fā)生),或按鈕是不亮的。

為了對(duì)這種事件建模,在圖9-15中給出了ElevatorEventLoop狀態(tài)。通過狀態(tài)圖左上角的事件“按下按鈕時(shí),按鈕已亮”執(zhí)行空操作,對(duì)按鈕已亮的情況進(jìn)行建模。另一種情況,通過標(biāo)有事件“按下按鈕時(shí),按鈕未亮”的箭頭指向的狀態(tài)ProcessingNewRequest,對(duì)按鈕未亮的情況進(jìn)行建模。

現(xiàn)在考慮場(chǎng)景中的事件3“一部電梯到達(dá)3樓”,可推廣到電梯在任意樓層間移動(dòng)的情形。其他的狀態(tài)圖相對(duì)比較簡(jiǎn)單,留作練習(xí)。

9.4.6測(cè)試工作流:電梯問題案例研究

現(xiàn)在,功能、實(shí)體類和動(dòng)態(tài)模型都已經(jīng)建好了,下面要進(jìn)行測(cè)試工作流,以檢查之前完成的分析工作流,可以使用CRC卡片。

相應(yīng)地,為每個(gè)實(shí)體類編寫CRC卡片:Button類、ElevatorButton類、FloorButton類、Elevator類和ElevatorController類。圖9-16所描述的ElevatorController類的CRC卡片是從圖9-13的類圖和圖9-15的狀態(tài)圖推導(dǎo)出來(lái)的。

確切地說,ElevatorController類的責(zé)任是通過列舉出ElevatorController類狀態(tài)圖(圖9-15)中的所有操作而得到的。通過分析圖9-14的類圖,可以確定ElevatorController類的協(xié)作類,也可看到ElevatorButton類、FloorButton類和Elevator類與ElevatorController類之間的交互關(guān)系。

該CRC卡片反映了面向?qū)ο蠓治龅谝淮蔚械膬蓚€(gè)主要問題。

(1)修改發(fā)現(xiàn)的問題??紤]責(zé)任“打開電梯按鈕”,在面向?qū)ο蠓缎屠?,該命令是不合適的。從責(zé)任驅(qū)動(dòng)設(shè)計(jì)的觀點(diǎn)看,ElevatorButton類的對(duì)象(實(shí)例)負(fù)責(zé)將自己打開或關(guān)閉。從信息隱藏的觀點(diǎn)來(lái)看,ElevatorController類不知道ElevatorButton類如何打開一個(gè)按鈕。正確的責(zé)任應(yīng)該是:發(fā)送一條消息給ElevatorButton類,讓其自己打開。圖9-16的責(zé)任2~6需要進(jìn)行類似的調(diào)整。這些調(diào)整反映在圖9-17的ElevatorController類的CRC卡片的第二次迭代中。

(2)忽略某個(gè)類。回到圖9-17,考慮責(zé)任7“打開電梯門并啟動(dòng)定時(shí)器”,狀態(tài)的概念有助于確定某個(gè)組件是否需要建模成類。如果要考慮的組件包含某個(gè)在實(shí)現(xiàn)過程中發(fā)生變化的狀態(tài),那么就很有可能建模成類。很顯然,電梯門包含一個(gè)狀態(tài)(開或關(guān)),所以ElevatorDoors應(yīng)該是一個(gè)類。

圖9-16對(duì)ElevatorController的CRC卡片的第一次迭代圖9-17對(duì)ElevatorController類的CRC卡片的第二次迭代

為什么ElevatorDoors應(yīng)該是一個(gè)類,還有另一個(gè)原因,面向?qū)ο蠓缎驮试S狀態(tài)隱藏在對(duì)象里以防止非法改變。如果存在某個(gè)ElevatorDoors類的對(duì)象,打開或關(guān)閉電梯門的唯一的方法是發(fā)送一條消息給ElevatorDoors類的對(duì)象。在錯(cuò)誤的時(shí)間打開或關(guān)閉電梯門,可能會(huì)導(dǎo)致嚴(yán)重的事故。

增加ElevatorDoors類意味著圖9-17的責(zé)任7和責(zé)任8需要調(diào)整,同樣,從責(zé)任1到責(zé)任6也需要調(diào)整。即需要發(fā)送消息給ElevatorDoors類的實(shí)例,使其打開或關(guān)閉。

還有一個(gè)問題,責(zé)任7是“打開電梯門并啟動(dòng)定時(shí)器”,該責(zé)任必須分解成兩個(gè)單獨(dú)的責(zé)任。當(dāng)然,必須發(fā)送一條消息給ElevatorDoors類來(lái)打開門。但是,定時(shí)器是ElevatorController類的一部分,因此啟動(dòng)定時(shí)器是ElevatorController類的責(zé)任。ElevatorController類的CRC卡片的第二次迭代(如圖9-18所示)表明該責(zé)任的分離已圓滿

完成。

除了圖9-17的CRC卡片反映的兩個(gè)主要問題外,ElevatorController類的責(zé)任“檢查請(qǐng)求集”和“更新請(qǐng)求集”需要增加屬性requests(請(qǐng)求)到ElevatorController類中。這里,只是簡(jiǎn)單地定義requests的類型為requestType,requests的數(shù)據(jù)結(jié)構(gòu)將在設(shè)計(jì)工作流中確定。

修改過的類圖如圖9-18所示。由于對(duì)類圖進(jìn)行了調(diào)整,用例圖和狀態(tài)圖也應(yīng)重新檢查,看其是否需要進(jìn)行修改。用例圖顯然不用修改。但是,必須重新調(diào)整圖9-15的狀態(tài)圖中的操作以反映圖9-18中的責(zé)任(CRC卡片第二次迭代),而非圖9-17中的責(zé)任(第一次迭代)。

另外,狀態(tài)圖必須擴(kuò)展以包含新增的類。圖9-19顯示了圖9-11場(chǎng)景的第二次迭代。

圖9-18電梯問題案例研究類圖的第三次迭代圖9-19電梯問題案例研究的正常場(chǎng)景的第二次迭代

9.5提取邊界類和控制類

與實(shí)體類不同,邊界類通常比較容易提取。一般來(lái)說,每個(gè)輸入屏幕、輸出屏幕和打印報(bào)告都可以建模成邊界類。例如,對(duì)打印報(bào)告建模的邊界類包括所有可能包含在報(bào)告里的不同數(shù)據(jù)項(xiàng)和打印報(bào)告所需執(zhí)行的不同操作。

通常,控制類同樣很容易提取,每個(gè)重要的計(jì)算都可以建模成一個(gè)控制類。

下面通過提取考勤系統(tǒng)實(shí)例研究中的類來(lái)說明實(shí)體類、邊界類和控制類的提取。圖9-20的用例圖是上一章獲取的需求。

圖9-20考勤系統(tǒng)案例研究用例圖的第2次迭代

9.6初始功能模型:考勤系統(tǒng)實(shí)例研究

下面,通過考勤系統(tǒng)來(lái)實(shí)踐分析過程。前面,已經(jīng)完成了考勤應(yīng)用程序的需求收集,下一步就是分析需求,將其轉(zhuǎn)換成開發(fā)人員可以理解的語(yǔ)言。這個(gè)階段,還不用去考慮特殊的技術(shù),關(guān)心的是該模型的內(nèi)部是如何工作的。

這里,從用例分級(jí)開始經(jīng)歷一系列步驟,接著尋找候選的對(duì)象以及它們之間的交互,最后詳細(xì)地描述這些類。

9.6.1劃分用例等級(jí)

每個(gè)用例都要根據(jù)其風(fēng)險(xiǎn)、對(duì)用戶和構(gòu)架的重要性、對(duì)團(tuán)隊(duì)是否有能力開發(fā)等方面劃分等級(jí)。一旦用例按這些類別來(lái)分類,就可以確定哪個(gè)用例的子集是最重要的,并適合在第一個(gè)迭代中實(shí)現(xiàn)。該過程包括一系列權(quán)衡和妥協(xié)的綜合考慮。例如,一個(gè)用例的風(fēng)險(xiǎn)可能很高,就想在第一次選代中實(shí)現(xiàn)它,但是,如果開發(fā)團(tuán)隊(duì)對(duì)實(shí)現(xiàn)該用例完全沒有把握,那么,作為妥協(xié),就應(yīng)該選擇一個(gè)風(fēng)險(xiǎn)較低、容易實(shí)現(xiàn)的用例。

1.分級(jí)系統(tǒng)

通常,可以將用例的風(fēng)險(xiǎn)、重要性、適用性分成1~5個(gè)數(shù)字表示的等級(jí)。級(jí)別越高,該用例就越適合在第一次或者下一次選代中實(shí)現(xiàn)。

前面,考勤應(yīng)用系統(tǒng)中找到了6個(gè)用例,圖9-21顯示了其用例圖,與圖9-20沒有什么不同,只是將名稱用英文標(biāo)識(shí)了而已??梢詮娘L(fēng)險(xiǎn)、重要性以及對(duì)當(dāng)前開發(fā)團(tuán)隊(duì)的合適性等方面來(lái)描述每個(gè)用例。

圖9-21考勤應(yīng)用系統(tǒng)的頂層用例圖

1)風(fēng)險(xiǎn)

在考慮用例的風(fēng)險(xiǎn)之前,需要先列出項(xiàng)目的風(fēng)險(xiǎn)清單。以下的風(fēng)險(xiǎn),對(duì)多數(shù)的項(xiàng)目來(lái)說都是存在的,可以作為考慮項(xiàng)目風(fēng)險(xiǎn)的出發(fā)點(diǎn)。

無(wú)法接受的系統(tǒng)性能;

無(wú)法接受的用戶界面;

不確定的進(jìn)度以及開發(fā)周期;

無(wú)法應(yīng)付新的需求。

經(jīng)過考慮,該系統(tǒng)的用戶界面相對(duì)簡(jiǎn)單,但也意識(shí)到,系統(tǒng)性能很關(guān)鍵,最終用戶可能很忙,不希望由于考勤系統(tǒng)的原因而造成延遲。根據(jù)在以往項(xiàng)目中的經(jīng)驗(yàn),過一段時(shí)間,相關(guān)人員總是不可避免地要增加系統(tǒng)的規(guī)模,讓一些新的特性無(wú)縫地添加到系統(tǒng)中。這樣,將系統(tǒng)風(fēng)險(xiǎn)按如下順序排列,并決定按照這個(gè)順序來(lái)考慮每個(gè)用例。

無(wú)法接受的系統(tǒng)性能;

無(wú)法應(yīng)付新的需求;

不確定的進(jìn)度以及開發(fā)周期;

無(wú)法接受的用戶界面。

在按風(fēng)險(xiǎn)分級(jí)用例之前,需要有一個(gè)描述用例級(jí)別的簡(jiǎn)單方法??稍儐栭_發(fā)人員這樣的問題:他是否有把握在第一次嘗試中解決某個(gè)問題,然后讓他從下面的答案中選擇一個(gè)。

當(dāng)然可以,項(xiàng)目團(tuán)隊(duì)以前解決過這種問題;

沒問題,組織以前解決過這種問題;

可以采用第三方提供的產(chǎn)品、培訓(xùn)、書籍或其他的技術(shù)資源,但團(tuán)隊(duì)內(nèi)部沒有任何經(jīng)驗(yàn);

可能吧,聽說過類似的可以解決的問題;

希望可以,但需要做一些開創(chuàng)性的工作。

在評(píng)估用例的時(shí)候可以發(fā)現(xiàn),這個(gè)簡(jiǎn)單的風(fēng)險(xiǎn)“譜”將有助于識(shí)別出在下一次迭代中必須考慮的高風(fēng)險(xiǎn)用例。

2)重要性

如果一個(gè)用例差不多就是系統(tǒng)的愿景,那它對(duì)用戶及構(gòu)架就很重要,一個(gè)重要的用例應(yīng)該能夠體現(xiàn)系統(tǒng)的特性和目標(biāo)。其他的用例也可能會(huì)很重要,但只是扮演支持的角色。例如,如果沒有“AddEmployee”用例,那么考勤系統(tǒng)將無(wú)法運(yùn)行。另一方面,“RecordTime”和“ExportTimeEntries”用例則完全體現(xiàn)了系統(tǒng)的目的。

那么,是否可以這樣衡量用例的重要性:可以詢問開發(fā)人員,如果該用例在本次迭代中忽略掉,或用其他的用例來(lái)取代,用戶會(huì)怎樣?讓其從下面的答案中選擇一個(gè)。

幾乎不會(huì)注意到該用例不存在,在沒有它的情況下使用系統(tǒng)不會(huì)有什么影響;

會(huì)注意到該用例不存在,但是,稍加想象,系統(tǒng)仍然可以很好的使用;

系統(tǒng)的大部分可以獨(dú)立于該用例;

系統(tǒng)的一部分可以獨(dú)立于該用例;

沒有它,就不可能使用系統(tǒng)。

3)合適性

如果項(xiàng)目組可以只經(jīng)過最少的培訓(xùn)以及相對(duì)短的學(xué)習(xí)就可以開始開發(fā)某個(gè)用例,那么該用例就比較合適。當(dāng)在機(jī)構(gòu)中引入新的技術(shù)、語(yǔ)言和開發(fā)方法時(shí),這兩個(gè)標(biāo)準(zhǔn)就特別

重要。

但是,在第一次迭代選擇用例的時(shí)候并沒有考慮到技術(shù)選擇,因此很難判斷開發(fā)某個(gè)用例時(shí)需要學(xué)習(xí)多少東西。實(shí)際上,項(xiàng)目組一般都知道是否需要采用一種新技術(shù),例如,面向?qū)ο箝_發(fā)。而且,一般也知道要采用的語(yǔ)言。因此,可以要求開發(fā)人員描述對(duì)方法和技術(shù)的把握有多大,讓其從下面的答案中做出選擇。

團(tuán)隊(duì)絕對(duì)需要一段培訓(xùn)時(shí)間才能開發(fā)該用例;

對(duì)于該用例來(lái)說,團(tuán)隊(duì)可能有足夠的能力,但是,在一次迭代之后,團(tuán)隊(duì)的能力需要有本質(zhì)的提高;

團(tuán)隊(duì)可能有足夠的能力,但是,在一次迭代之后,團(tuán)隊(duì)的能力不需要怎么提高;

不需要很多的培訓(xùn),要么是團(tuán)隊(duì)的能力已經(jīng)綽綽有余,要么是該用例相當(dāng)簡(jiǎn)單;

不需要很多的培訓(xùn),團(tuán)隊(duì)有足夠的經(jīng)驗(yàn),用例也很簡(jiǎn)單,手到擒來(lái)。

在例子中,假設(shè)開發(fā)團(tuán)隊(duì)經(jīng)驗(yàn)豐富,絕大多數(shù)的開發(fā)人員至少有一年的面向?qū)ο箝_發(fā)經(jīng)驗(yàn),幾乎人人都有至少一年的Java和關(guān)系數(shù)據(jù)庫(kù)的開發(fā)經(jīng)驗(yàn)。

下面,按風(fēng)險(xiǎn)、重要性、合適性來(lái)評(píng)估用例,找出那些應(yīng)該在第一次迭代中實(shí)現(xiàn)的用例。

2.評(píng)估“ExportTimeEntries”用例

“ExportTimeEntries”用例允許管理員導(dǎo)出指定工時(shí)條目到格式化的XML文件中。

1)風(fēng)險(xiǎn)

當(dāng)然,這里包括性能方面的風(fēng)險(xiǎn)。隨著時(shí)間的流逝和新用戶的加入,系統(tǒng)的數(shù)據(jù)不斷增多,從中抽取數(shù)據(jù)塊所需的時(shí)間也越多,但該任務(wù)可以在非高峰時(shí)間執(zhí)行。

該用例必須是可擴(kuò)展的。因?yàn)槌槿】记诳l目的標(biāo)準(zhǔn)將會(huì)隨著時(shí)間而演化并變得更復(fù)雜;

該用例比較容易估計(jì),僅僅是找到考勤卡條目,然后將數(shù)據(jù)寫到一個(gè)文件中;

用戶界面比較簡(jiǎn)單,所以,沒有提交復(fù)雜用戶界面的真正風(fēng)險(xiǎn)。

總之,該用例的風(fēng)險(xiǎn)看起來(lái)比較低,評(píng)為第2級(jí)—“沒問題,組織以前解決過這類問題”看起來(lái)比較合適。

2)重要性

這是一個(gè)非常重要的用例,整個(gè)考勤系統(tǒng)的功能就是為各種不同的目標(biāo)收集并獲取考勤卡條目,評(píng)為第5級(jí)—“沒有它,系統(tǒng)就不可能使用”比較合適。

3)合適性

該用例相對(duì)簡(jiǎn)單,團(tuán)隊(duì)可以解決,評(píng)為第4級(jí)—“不需要很多的經(jīng)驗(yàn),要么是團(tuán)隊(duì)的能力已經(jīng)綽綽有余,要么是該用例相當(dāng)簡(jiǎn)單”比較合適。

4)結(jié)論

考慮到重要性,該用例顯然應(yīng)該在第一次迭代中實(shí)現(xiàn)。這有助于同用戶建立信任,并提供重要的構(gòu)架功能。

3.評(píng)估“Login”用例

作為執(zhí)行其他更有意義的用例的先決條件,“Login”用例執(zhí)行用戶身份驗(yàn)證。

1)風(fēng)險(xiǎn)

這里會(huì)有性能上的風(fēng)險(xiǎn),因?yàn)椋赡軙?huì)有大量的用戶同時(shí)登錄系統(tǒng)。但是,登錄是一個(gè)相當(dāng)簡(jiǎn)單的過程,并不涉及很多的數(shù)據(jù)或計(jì)算,性能風(fēng)險(xiǎn)較低。

登錄是很容易理解的用例,可擴(kuò)展性的風(fēng)險(xiǎn)很低;

登錄用例沒有什么進(jìn)度風(fēng)險(xiǎn),它很小而且集中;

不存在無(wú)法接受的用戶界面風(fēng)險(xiǎn)。

評(píng)為第1級(jí)—“當(dāng)然可以,項(xiàng)目組以前解決過這種問題”完全適合該用例的情況。

2)重要性

在最終系統(tǒng)中,如果沒有該用例,系統(tǒng)就完全無(wú)法接受。但是,最終用戶完全可以在沒有該用例的情況下評(píng)估系統(tǒng)。然而,即使該用例不包括在第一次迭代中,開發(fā)人員還是需要確保其構(gòu)架支持該用例。

評(píng)為第2級(jí)—“用戶會(huì)注意到?jīng)]有該用例,但是,稍加想象,系統(tǒng)仍然可以很好地使用”看起來(lái)比較合適。

3)合適性

評(píng)為第4級(jí)—“不需要很多的培訓(xùn),要么是團(tuán)隊(duì)的能力已經(jīng)足以應(yīng)付,要么是該用例相當(dāng)簡(jiǎn)單”看起來(lái)相當(dāng)合適。

4)結(jié)論

盡管該用例在構(gòu)架上的重要性仍然有所保留,但是,“Login”在第一次迭代時(shí)不是特別重要。

4.評(píng)估“RecordTime”用例

“RecordTime”用例允許用戶在當(dāng)前的時(shí)間段中輸入工時(shí)。

1)風(fēng)險(xiǎn)

性能上的風(fēng)險(xiǎn)是很明顯的,因?yàn)樵诿總€(gè)時(shí)間段的最后幾個(gè)小時(shí)會(huì)有大量的用戶要登記工時(shí)。而且,用戶在執(zhí)行這些任務(wù)的時(shí)候,糟糕的系統(tǒng)性能表現(xiàn)往往會(huì)讓他們受不了。例如,雇員可能會(huì)心甘情愿地花上15分鐘以等待和下載一個(gè)有趣的視頻剪輯,但是,在雜貨店中排上3分鐘的隊(duì),就會(huì)感到很惱火。填寫考勤卡一般來(lái)說是屬于那類不受歡迎的工作類別,所以必須避免性能問題。

該用例看起來(lái)很容易理解,可擴(kuò)展性的風(fēng)險(xiǎn)很低;

考慮到復(fù)雜性和性能需求,對(duì)該用例的估計(jì)是很復(fù)雜的;

用戶界面相當(dāng)復(fù)雜,需要有收費(fèi)項(xiàng)目代碼選項(xiàng)、條目說明以及一個(gè)可編輯的時(shí)間條目矩陣。

由于性能需求和用戶界面的復(fù)雜性,“RecordTime”用例有很大的風(fēng)險(xiǎn),評(píng)為第3級(jí)—“可以采用第三方提供的產(chǎn)品、培訓(xùn)、書籍或其他的技術(shù)資源,但內(nèi)部沒有任何經(jīng)驗(yàn)”比較合適。

2)重要性

“RecordTime”用例很重要,體現(xiàn)了考勤系統(tǒng)的意圖。一個(gè)不包含該用例的迭代根本讓人無(wú)法想象,可以評(píng)為第5級(jí)—“沒有它,系統(tǒng)就不可能使用”。

3)合適性

復(fù)雜性和風(fēng)險(xiǎn)要求在第一次迭代中包含該用例,同時(shí)也需要認(rèn)真評(píng)估,看其是否適合開發(fā)團(tuán)隊(duì),評(píng)為第2級(jí)—“對(duì)該用例來(lái)說,團(tuán)隊(duì)可能有足夠的能力,但是,在一次迭代之后,團(tuán)隊(duì)的能力需要有本質(zhì)的提高”看起來(lái)比較合適。

4)結(jié)論

顯然,諸多因素使得必須在第一次迭代中包含“RecordTime”用例。但是,由于復(fù)雜性,需要在頭兩次迭代中來(lái)完成該用例的開發(fā)以滿足相關(guān)人員的需求。例如,在第一次迭代中可以完成用戶界面,而將性能留到下一次迭代。

5.選擇第一次迭代的用例

對(duì)于一個(gè)有開發(fā)經(jīng)驗(yàn)的團(tuán)隊(duì),就可以在風(fēng)險(xiǎn)和重要性的基礎(chǔ)上確定第一次迭代的用例,上面只是分析了關(guān)鍵用例,其他的省略了?!癛ecordTime”和“ExportTimeEntries”肯定應(yīng)該屬于第一次迭代,“CreateEmployee”、“CreateChargeCode”和“ChangePassword”可以推遲實(shí)現(xiàn),“Login”也可以推遲,但是可以將它包含進(jìn)來(lái),使第一次迭代更真實(shí)。

將所有對(duì)構(gòu)架重要的用例都放在第一次迭代中,在這次迭代完成后,相關(guān)人員就可以得到關(guān)于系統(tǒng)的清晰的印象,而且開發(fā)者可以通過這幾個(gè)關(guān)鍵用例來(lái)確保解決方案的完

整性。

在選定了第一次迭代的用例之后,下面要完成剩下的分析步驟。

9.6.2尋找候選對(duì)象

這一步,開發(fā)人員要找出提供用例功能的對(duì)象,可以將對(duì)象劃分為三種類型:實(shí)體類、邊界類和控制類,這樣,可以大大簡(jiǎn)化該過程。

在尋找對(duì)象的時(shí)候,很重要的一點(diǎn),就是要限制每個(gè)對(duì)象的責(zé)任,并為每個(gè)對(duì)象以及對(duì)象的每個(gè)方法采用一致的命名。

由于剛剛開始進(jìn)行分析,所以不會(huì)花很多的時(shí)間來(lái)確定對(duì)象之間的關(guān)系。在后面的步驟中,這些關(guān)系將會(huì)得到澄清。因此,要盡量保持簡(jiǎn)單,不要試圖去完成一個(gè)完美的草圖。

1.尋找實(shí)體對(duì)象

對(duì)每個(gè)用例,搜索每個(gè)事件流來(lái)尋找名詞、數(shù)據(jù)和行為。名詞將會(huì)成為實(shí)體對(duì)象,數(shù)據(jù)則可能會(huì)是對(duì)象的屬性,而行為將分配給一個(gè)或多個(gè)對(duì)象。每個(gè)用例中的名詞先單獨(dú)考慮,然后再綜合考慮。

1)“RecordTime”用例

瀏覽一下該用例的正常事件流,關(guān)注下面的對(duì)象和數(shù)據(jù)。

雇員查看當(dāng)前時(shí)間段之前輸入的數(shù)據(jù);

雇員從已有的支付號(hào)碼中選擇一個(gè),這些收費(fèi)代碼按客戶和項(xiàng)目組織;

雇員為當(dāng)前的時(shí)間段選擇日期;

雇員輸入以正整數(shù)表示的時(shí)間數(shù);

在視圖中顯示數(shù)據(jù),在以后的視圖中可以看到該數(shù)據(jù)。

下面是在第一個(gè)可選事件流——雇員編輯已有的數(shù)據(jù)中需要強(qiáng)調(diào)的部分。

雇員看到當(dāng)前時(shí)間段之前輸入的數(shù)據(jù);

雇員選擇一個(gè)已有的條目;

雇員修改工時(shí)和/或支付號(hào)碼;

在視圖中更新信息,在以后的視圖中可以看到。

以下則是在第二個(gè)可選事件流——提交考勤卡作為結(jié)束中需要強(qiáng)調(diào)的部分。

雇員看到當(dāng)前時(shí)間段之前輸入的數(shù)據(jù);

雇員選擇提交考勤卡;

系統(tǒng)要求雇員確認(rèn)提交,提醒雇員將不能再編輯這些條目;

提交考勤卡,不能再進(jìn)行編輯。

在剩下的事件流中沒有再引入新的信息,下面,列出名詞列表,然后逐個(gè)判斷,剔除那些不需要的和重復(fù)的實(shí)體對(duì)象,同時(shí),識(shí)別那些不適合作為一個(gè)獨(dú)立的對(duì)象、而應(yīng)該是其他對(duì)象屬性的名詞。

收費(fèi)代碼。

支付號(hào)碼。顯然,這兩個(gè)詞是同義詞,由于在其他文檔中,收費(fèi)代碼使用更普遍,所以丟棄支付號(hào)碼,選擇收費(fèi)代碼作為一類實(shí)體對(duì)象。

客戶??蛻艨雌饋?lái)是一類實(shí)體對(duì)象。

日期。日期似乎不是一個(gè)獨(dú)立的對(duì)象類型,相反,更像是對(duì)象中的數(shù)據(jù)。

雇員。雇員應(yīng)該是一個(gè)獨(dú)立的實(shí)體對(duì)象。

已有的條目。考勤卡中的一個(gè)條目可能是一個(gè)保存日期的對(duì)象,姑且認(rèn)為它是一類實(shí)體對(duì)象。

時(shí)間數(shù)。

工時(shí)。這兩個(gè)是同義詞,但是,工時(shí)更有意義,所以丟棄時(shí)間數(shù)。工時(shí)成為一個(gè)剛發(fā)現(xiàn)的條目對(duì)象的數(shù)據(jù)。

以前輸入的數(shù)據(jù)。與條目對(duì)象相同,所以丟棄掉。

項(xiàng)目。項(xiàng)目是一類實(shí)體對(duì)象。

考勤卡。考勤卡是一類實(shí)體對(duì)象。

時(shí)間段。時(shí)間段描述一個(gè)考勤卡,所以是考勤卡對(duì)象的數(shù)據(jù)。

視圖。視圖是邊界對(duì)象,所以排除掉。

這樣,“RecordTime”用例就分析完畢,實(shí)體對(duì)象有:收費(fèi)項(xiàng)目代碼、客戶、雇員、已有的條目、工時(shí)、項(xiàng)目和考勤卡。

2)“ExportTimeEntries”用例

瀏覽一下“ExportTimeEntries”用例的正常事件流,關(guān)注下面的候選對(duì)象和數(shù)據(jù)。

管理員選擇一段日期;

管理員選擇一些或所有的客戶;

管理員選擇一些或所有的雇員;

管理員選擇目標(biāo)文件;

數(shù)據(jù)以XML格式導(dǎo)出到文件中,過程結(jié)束后通知管理員。

下一步,列出名詞列表,然后逐個(gè)判斷。

管理員。管理員應(yīng)該是一個(gè)實(shí)體對(duì)象。

客戶。客戶已經(jīng)識(shí)別為一類實(shí)體對(duì)象了。

?XML格式。這個(gè)是對(duì)輸出文件的描述而不是實(shí)體對(duì)象。

數(shù)據(jù)。這里的數(shù)據(jù)指的是一組考勤卡中的一組條目,已經(jīng)是實(shí)體對(duì)象了,沒有必要再增加新對(duì)象。

雇員。雇員是已經(jīng)識(shí)別出來(lái)的對(duì)象。

一段日期。一段日期是在另一個(gè)對(duì)象中的數(shù)據(jù)。增加一個(gè)新的實(shí)體對(duì)象——輸出請(qǐng)求,雖然它并沒有在事件流中出現(xiàn)。

目標(biāo)文件。這個(gè)顯然是作為輸出請(qǐng)求的一個(gè)數(shù)據(jù)。

這樣,在該用例中,得到兩個(gè)新對(duì)象:管理員和輸出請(qǐng)求。接下來(lái)看看下一個(gè)用例。

3)“Login”用例

瀏覽一下“Login”用例的正常事件流,關(guān)注下面的候選對(duì)象和數(shù)據(jù)。

管理員或雇員輸入用戶名和密碼。

驗(yàn)證用戶是管理員還是雇員,用戶在登錄的時(shí)候并沒有選擇身份,是由系統(tǒng)根據(jù)用戶名確定的。

現(xiàn)在列出名詞列表,然后逐個(gè)判斷。

管理員。管理員已經(jīng)識(shí)別為一類實(shí)體對(duì)象了。

雇員。雇員已經(jīng)識(shí)別為一類實(shí)體對(duì)象了。

密碼。密碼應(yīng)該是管理員對(duì)象或雇員對(duì)象的數(shù)據(jù)。

用戶。用戶應(yīng)該是管理員或雇員的一個(gè)更通用的類別。

用戶名。用戶名應(yīng)該是管理員對(duì)象或雇員對(duì)象的數(shù)據(jù)。

評(píng)估完該用例,沒有得到新的對(duì)象。

4)合并實(shí)體對(duì)象

得到下面的實(shí)體對(duì)象表。

管理員、收費(fèi)代碼、客戶、雇員、已有的條目、工時(shí)、項(xiàng)目、考勤卡。

這里只有兩個(gè)實(shí)體對(duì)象看起來(lái)比較相似,即管理員和雇員,都是用戶類,—個(gè)有管理員權(quán)限而另一個(gè)沒有,所以可以刪除這兩個(gè)類并增加用戶類。

圖9-22所示的類圖顯示了這些實(shí)體對(duì)象。

圖9-22實(shí)體類

2.尋找邊界對(duì)象

下一步是識(shí)別邊界對(duì)象。在分析階段,尋找邊界對(duì)象的規(guī)則是:每一對(duì)參與者、用例對(duì)應(yīng)一個(gè)邊界對(duì)象。

對(duì)“ExportTimeEntries”用例,有一個(gè)作為管理員和系統(tǒng)接口的邊界對(duì)象,就得到了一個(gè)作為系統(tǒng)和外部支付系統(tǒng)接口的邊界對(duì)象。

對(duì)“RecordTime”用例,根據(jù)這個(gè)規(guī)則可以找到兩個(gè)邊界對(duì)象:一個(gè)是作為管理員和系統(tǒng)的接口,另一個(gè)是普通雇員和系統(tǒng)的接口。盡管前面將管理員和雇員合并為一個(gè)實(shí)體對(duì)象,但是,邊界對(duì)象是由人們或外部系統(tǒng)如何使用系統(tǒng)來(lái)決定的,而不是由它們?cè)谙到y(tǒng)中是如何表示來(lái)確定。

對(duì)“Login”用例,根據(jù)這個(gè)規(guī)則可以找到兩個(gè)邊界對(duì)象:一個(gè)是作為管理員和系統(tǒng)的接口,而另一個(gè)是普通雇員和系統(tǒng)的接口。

用標(biāo)準(zhǔn)的命名規(guī)范可以簡(jiǎn)化該過程,可以用UI作為用戶界面對(duì)象的后綴,用SystemInterface作為系統(tǒng)接口的后綴。如果有多個(gè)參與者觸發(fā)一個(gè)用例,邊界對(duì)象就得分別命名。應(yīng)用這些規(guī)則,就得到如圖9-23所示的邊界類。

3.尋找控制類

在分析過程中,尋找控制類的規(guī)則是每個(gè)用例分配類控制對(duì)象。每個(gè)控制對(duì)象為一個(gè)用例封裝工作流,這樣實(shí)體對(duì)象就可以保持集中,而由控制對(duì)象向邊界對(duì)象提供簡(jiǎn)單的接口。

在為控制對(duì)象命名時(shí),要保持簡(jiǎn)潔,可以選擇一個(gè)合理的后綴,如Workflow,這樣做有利于系統(tǒng)的理解。在很多時(shí)候,只要在用例名后加一個(gè)Workflow就可以了。在命名風(fēng)格上,并沒有什么限制,簡(jiǎn)單和一致才是最重要的。

對(duì)“ExportTimeEntries”用例,根據(jù)規(guī)則可以得到一個(gè)叫做“ExportTimeEntriesWorkflow”的控制類;

對(duì)“RecordTime”用例,根據(jù)規(guī)則可以得到一個(gè)叫做“RecordTimeWorkflow”的控制類;

對(duì)“Login”用例,根據(jù)規(guī)則可以得到一個(gè)叫做“LoginWorkflow”的控制類。

圖9-24顯示這些控制類。

在很多情況下,了解實(shí)體對(duì)象如何使用更有意義,因此,進(jìn)入下一步,描述對(duì)象交互。

圖9-24控制類

9.7分

下面是分析一個(gè)類的目的(如圖9-25所示)。

依據(jù)分析類在用例實(shí)現(xiàn)中的角色來(lái)確定和維護(hù)它的職責(zé);

確定和維護(hù)分析類的屬性及其關(guān)系;

捕獲分析類實(shí)現(xiàn)的特殊需求。圖9-25分析類的輸入和結(jié)果

9.7.1確定職責(zé)

組合一個(gè)類在不同用例實(shí)現(xiàn)中充當(dāng)?shù)慕巧梢詤R集該類的職責(zé),研究類圖和交互圖可以確定類參與的用例實(shí)現(xiàn)。還要記住,對(duì)于類的每個(gè)用例實(shí)現(xiàn)的需求,有時(shí)是在用例實(shí)現(xiàn)的事件流分析中用文本進(jìn)行描述的。

舉例:類的角色

“賬單”對(duì)象是在用例“給買主開單”中創(chuàng)建的。賣主執(zhí)行該用例來(lái)請(qǐng)求買主支付訂單(訂單是在用例“訂購(gòu)貨物或服務(wù)”中創(chuàng)建的)。在這個(gè)用例期間,賬單傳遞給買主,隨后由他決定支付賬單。

“支付”在“支付賬單”用例中實(shí)現(xiàn),此時(shí)“支付調(diào)度程序”對(duì)象調(diào)度“賬單”對(duì)象來(lái)確定支付日期。之后,支付賬單,并關(guān)閉“賬單”對(duì)象。

需要注意,參與用例“給買主開單”和用例“支付賬單”的是“賬單”對(duì)象的同一個(gè)實(shí)例。

有多種方式可以匯集類的職責(zé)。一種簡(jiǎn)單的方法是每次從一個(gè)角色中抽取出職責(zé),再附加上每次基于一個(gè)用例實(shí)現(xiàn)得到的補(bǔ)充職責(zé)或修改現(xiàn)有的職責(zé)。

舉例:類的職責(zé)

“支付調(diào)度程序”類有以下職責(zé):

創(chuàng)建一個(gè)支付請(qǐng)求;

跟蹤已確定支付時(shí)間的支付,當(dāng)實(shí)施支付或取消支付時(shí)發(fā)送一條通知;

在規(guī)定的支付日期啟動(dòng)金額的轉(zhuǎn)賬;

當(dāng)賬單已確定了支付日期和已經(jīng)支付(即關(guān)閉)時(shí),通知“賬單”對(duì)象。

9.7.2確定屬性

屬性詳細(xì)說明了分析類的特性,一般由類的職責(zé)直接或間接決定。在確定屬性時(shí),應(yīng)記住下面常識(shí)性的指南。

屬性的名稱應(yīng)是一個(gè)名詞;

記住,屬性的類型在分析階段應(yīng)該是概念上的,如果可能的話,不應(yīng)受到實(shí)現(xiàn)環(huán)境的限制。例如,分析階段中“數(shù)量”可能是一種合適的類型,但在設(shè)計(jì)階段,它所對(duì)應(yīng)的類型應(yīng)為“整型”;

在選擇一種屬性類型時(shí),盡量重用已存在的類型;

一個(gè)簡(jiǎn)單的屬性實(shí)例不能由多個(gè)分析對(duì)象共享。如果需要這樣,屬性要在自己的類中進(jìn)行定義;

如果一個(gè)分析類由于自己的屬性變得過于復(fù)雜而難以理解,可以將其中的一些屬性分成它們自己的類;

實(shí)體類的屬性通常很明顯。如果一個(gè)實(shí)體類可以跟蹤到一個(gè)領(lǐng)域類或一個(gè)業(yè)務(wù)實(shí)體類,這些類的屬性可作為重要的輸入;

與由人充當(dāng)?shù)膮⑴c者進(jìn)行交互的邊界類,其屬性經(jīng)常表示由該參與者所操作的信息項(xiàng),例如帶標(biāo)記的文本域;

與由系統(tǒng)充當(dāng)?shù)膮⑴c者進(jìn)行交互的邊界類,其屬性經(jīng)常表示通信接口的特性;

控制類由于其生命周期短暫,因此很少具有屬性。然而在用例實(shí)現(xiàn)期間,控制類可能會(huì)有代表聚集或派生價(jià)值的屬性;

有時(shí)并不需要形式化的屬性。相反,對(duì)由分析類處理的特性進(jìn)行簡(jiǎn)單說明就足夠了,而且還可以放到該類的責(zé)任描述中;

如果一個(gè)類具有很多屬性或復(fù)雜屬性時(shí),可以在一個(gè)只顯示屬性欄的單獨(dú)的類圖中加以說明。

9.7.3確定關(guān)聯(lián)和聚合

分析對(duì)象通過通信圖中的鏈進(jìn)行交互,這些鏈一般是分析對(duì)象的相應(yīng)類之間關(guān)聯(lián)的實(shí)例。因此,構(gòu)件工程師應(yīng)該研究通信圖中的鏈以便確定需要哪些關(guān)聯(lián),這些鏈表明對(duì)象間的引用和聚合。

類之間關(guān)系的數(shù)量應(yīng)盡量少。它主要不是指現(xiàn)實(shí)世界中那種能作為聚合或關(guān)聯(lián)來(lái)建模的關(guān)系,而是指為了響應(yīng)各種用例實(shí)現(xiàn)的需求而必須存在的關(guān)系。分析階段的重點(diǎn)不在于通過聚合或關(guān)聯(lián)來(lái)對(duì)最佳搜索路徑建模,這項(xiàng)工作最好放在設(shè)計(jì)和實(shí)現(xiàn)階段處理。

構(gòu)件工程師還要定義關(guān)聯(lián)的多重性、角色名稱、自關(guān)聯(lián)、關(guān)聯(lián)類、有序角色、限定角色和n元關(guān)聯(lián)。

舉例:分析類間的關(guān)聯(lián)

賬單是對(duì)一張或多張訂單的支付請(qǐng)求(如圖9-26所示),可以表示為一個(gè)帶有“1..*”多重性的關(guān)聯(lián)(一般至少有一張訂單與賬單關(guān)聯(lián))和角色名稱“支付訂單”。

圖9-26賬單與訂單之間的一對(duì)多關(guān)聯(lián)

當(dāng)對(duì)象表示下面的事物時(shí)應(yīng)該使用聚合。

實(shí)際中相互包容的概念,如汽車包含駕駛員和乘客;

相互間存在組成關(guān)系的概念,如汽車由發(fā)動(dòng)機(jī)和車輪等部件組成;

構(gòu)成對(duì)象的概念性集合的概念,如家庭由父親、母親和孩子組成。

9.7.4確定泛化

在分析階段,從幾個(gè)不同的分析類中抽取共享和公用的行為時(shí)應(yīng)該使用泛化,泛化應(yīng)處于較高的概念層,以使分析模型易于理解。

舉例:確定泛化

“賬單”類和“訂單”類具有相似的職責(zé),二者都是對(duì)象“交易”的特化,如圖9-27所示。

在設(shè)計(jì)階段,應(yīng)該對(duì)泛化關(guān)系進(jìn)行調(diào)整,以便更好地適應(yīng)所選的實(shí)現(xiàn)環(huán)境,如程序設(shè)計(jì)語(yǔ)言泛化有可能消失,而變?yōu)橛善渌P(guān)系(如關(guān)聯(lián))來(lái)實(shí)現(xiàn)。

圖9-27“交易”對(duì)象是“賬單”和“訂單”的泛化

9.7.5捕獲特殊需求

現(xiàn)在,將捕獲在分析階段中確定的、但應(yīng)該在設(shè)計(jì)和實(shí)現(xiàn)階段中進(jìn)行處理的分析類的所有需求(如非功能性需求)。在捕獲這些需求時(shí),務(wù)必要研究用例實(shí)現(xiàn)的特殊需求,因?yàn)樗鼈兛赡馨伺c分析類有關(guān)的補(bǔ)充(非功能性的)需求。

舉例:捕獲與分析類有關(guān)的特殊需求

下面是對(duì)“賬單”類的持久性需求的特征限定。

大小范圍(SizeRange):每個(gè)對(duì)象2K至1024K字節(jié)。

容量(Volume):最大為100000。

更新頻率(UpdateFrequency)。

創(chuàng)建/刪除:1000次/天。

更新:30次/小時(shí)。

讀?。涸L問1次/小時(shí)。

在捕獲這些需求時(shí),應(yīng)該盡可能參照已由構(gòu)架設(shè)計(jì)師確定的、公用的特殊需求。

9.8初始類圖:考勤系統(tǒng)實(shí)例研究

現(xiàn)在,要確定類之間的關(guān)系,這些關(guān)系是支持事件流中對(duì)象交互所必需的,可以通過類圖來(lái)完成。這意味著,同一個(gè)用例的幾個(gè)順序圖會(huì)共享一個(gè)類圖。

通過簡(jiǎn)單的工作,就可以確定一個(gè)關(guān)系是否必要。從一個(gè)對(duì)象發(fā)往另一個(gè)對(duì)象的每條消息都需要一個(gè)從發(fā)送對(duì)象類到接收對(duì)象類之間的關(guān)系。

如果一個(gè)發(fā)送對(duì)象創(chuàng)建一個(gè)接收對(duì)象,使用它,然后拋棄;或從方法的參數(shù)中獲取接收對(duì)象、使用它但不保存,就是一種依賴關(guān)系。在分析階段,這個(gè)關(guān)系可能比較難確定,因?yàn)檫@里沒有方法參數(shù)。因此,這種關(guān)系的確定在分析階段并不重要。

9.8.1尋找“Login”中的關(guān)系

在“Login”用例的正常事件流的順序圖中按順序?qū)ふ谊P(guān)系。EmployeeLoginUI對(duì)象調(diào)用LoginWorkflow對(duì)象中的validateLogin()方法,這意味著從EmployeeLoginUI類到LoginWorkflow類之間存在關(guān)系。從LoginWorkflow類到User類和UserLocator類之間也存在關(guān)系。返回值并不表明關(guān)系,因?yàn)閷?duì)象并不需要通過引用來(lái)返回消息。

在確定關(guān)系的方向之后,來(lái)考慮每個(gè)關(guān)系的類型。首先,對(duì)EmployeeLoginUI對(duì)象,保存對(duì)LoginWorkflow對(duì)象的引用似乎是沒必要的,然而,看一下“Login”用例的活動(dòng)圖,可以看到,EmployeeLoginUI允許用戶重新輸入姓名和密碼。這使得EmployeeLoginUI對(duì)象有必要保存對(duì)LoginWorkflow對(duì)象的引用。所以,這是一個(gè)關(guān)聯(lián)關(guān)系。

同樣的邏輯存在于LoginWorkflow對(duì)象和UserLocator對(duì)象之間的關(guān)系。LoginWorkflow對(duì)象需要保存一個(gè)引用來(lái)處理后續(xù)用戶的登錄,所以這是一個(gè)關(guān)聯(lián)關(guān)系。

LoginWorkflow對(duì)象不需要保存對(duì)User對(duì)象的引用,因?yàn)長(zhǎng)oginWorkflow每一次都要重新尋找User對(duì)象,所以這是一個(gè)依賴關(guān)系。圖9-28顯示了這些關(guān)系。

圖9-28參與“Login”用例的類

9.8.2尋找“RecordTime”中的關(guān)系

圖9-29顯示了這些關(guān)系。

RecordTimeUI對(duì)象使用RecordTimeWorkflow對(duì)象,后者又使用了User對(duì)象以及TimeCard對(duì)象。RecordTimeUI對(duì)象保存對(duì)RecodTimeWorkflow對(duì)象的引用,用它來(lái)更新條目,所以這是一個(gè)關(guān)聯(lián)關(guān)系。

RecordTimeWorkflow對(duì)象保存對(duì)User對(duì)象的引用,在RecordTimeWorkflow對(duì)象提交一個(gè)舊的考勤卡并使用新的考勤卡來(lái)替換時(shí)要使用到User對(duì)象,所以這是一個(gè)關(guān)聯(lián)關(guān)系。

圖9-29參與“RecordTime”用例的類

RecordTimeWorkflow對(duì)象保存對(duì)TimeCard對(duì)象的引用。在RecordTimeWorkflow對(duì)象為TimeCard對(duì)象設(shè)置條目的時(shí)候要用到TimeCard對(duì)象,所以這是一個(gè)關(guān)聯(lián)關(guān)系。

9.8.3尋找“ExportTimeEntries”中的關(guān)系

ExportEntriesUI對(duì)象要用到ClientLocator對(duì)象和UserLocator對(duì)象,也要用到ExportEntriesWorkflow對(duì)象。ExportEntriesWorkflow對(duì)象使用EntryLocator對(duì)象,BillingSystemInterface對(duì)象以及大量的Entry對(duì)象。沒有對(duì)象重用,所以,這里所有的關(guān)系都可以當(dāng)做依賴關(guān)系。

需要注意的一點(diǎn)是,ExportEntriesUI對(duì)象直接與ClientLocator和UserLocator對(duì)象交互,而不是通過控制對(duì)象。圖9-30顯示了這些關(guān)系。

圖9-30參與“ExportTimeEntries”用例的類

9.9描述分析對(duì)象間的交互

當(dāng)有了實(shí)現(xiàn)用例所需要的分析類的框架之后,就需要描述分析對(duì)象間如何進(jìn)行交互,可以使用順序圖、通信圖或活動(dòng)圖來(lái)實(shí)現(xiàn)。順序圖將交互關(guān)系表示為一個(gè)二維圖??v向是時(shí)間軸,時(shí)間沿豎線向下延伸。橫向代表了協(xié)作中各獨(dú)立對(duì)象的類元角色,類元角色用生命線表示。當(dāng)對(duì)象存在時(shí),角色用一條虛線表示,當(dāng)對(duì)象的過程處于激活狀態(tài)時(shí),生命線是一條雙道線。

通信圖包含了參與的參與者實(shí)例、分析對(duì)象以及它們的鏈接。如果該用例具有不同的或獨(dú)特的流或子流,通常值得為每個(gè)流創(chuàng)建一幅通信圖,這使用例實(shí)現(xiàn)更清晰,而且也能夠提取出表示通用和可重用的交互關(guān)系的通信圖。順序圖和通信圖在語(yǔ)義上是等價(jià)的,可以互相轉(zhuǎn)換,但兩者的側(cè)重點(diǎn)不同,順序圖關(guān)注交互的時(shí)間次序,通信圖關(guān)注對(duì)象間的交互和連接。

順序圖詳細(xì)而直觀地表現(xiàn)了一組相互協(xié)作的對(duì)象在執(zhí)行一個(gè)(或幾個(gè))用例時(shí)的行為依賴關(guān)系,以及服務(wù)和消息的時(shí)序關(guān)系。類圖對(duì)對(duì)象之間的消息(交互情況)表達(dá)得不夠詳細(xì),詳細(xì)說明對(duì)消息的表達(dá)雖然詳細(xì),但不夠直觀。順序圖既詳細(xì)又直觀,但一般只能表示少數(shù)幾個(gè)對(duì)象之間的交互。

順序圖可以幫助分析員對(duì)照檢查每個(gè)用例中描述的用戶需求,是否已經(jīng)落實(shí)到一些對(duì)象中去實(shí)現(xiàn);可以提醒分析員去補(bǔ)充遺漏的對(duì)象類或服務(wù);可以幫助分析員發(fā)現(xiàn)哪些對(duì)象是主動(dòng)對(duì)象;通過對(duì)一個(gè)特定的對(duì)象群體的動(dòng)態(tài)建模,深刻地理解對(duì)象之間的交互。

創(chuàng)建交互圖是從用例流的初期開始的,然后一次一步地通過用例流并決定實(shí)現(xiàn)該步需要哪些分析對(duì)象與參與者實(shí)例進(jìn)行交互。通??梢院茏匀坏卮_定對(duì)象在用例實(shí)現(xiàn)的交互序列中所處的位置。對(duì)于交互圖應(yīng)注意下面幾點(diǎn)。

可以從一個(gè)參與者實(shí)例向一個(gè)邊界對(duì)象發(fā)送一個(gè)消息來(lái)引入用例;

每個(gè)在先前步驟中確定的分析類應(yīng)至少有一個(gè)分析對(duì)象參與某個(gè)交互。否則,由于該分析類不參加任何用例實(shí)現(xiàn),就是多余的;

不要將消息指定給操作,因?yàn)椴]有為分析類確定操作。消息應(yīng)該表示出引用對(duì)象在與被引用對(duì)象交互時(shí)的意圖。這種“意圖”是接收對(duì)象的職責(zé)的根據(jù),甚至可能成為該職責(zé)的名稱;

通信圖中鏈接一般應(yīng)是分析類間關(guān)聯(lián)的實(shí)例,順序圖不關(guān)注鏈接。這可以概括出所有顯見的關(guān)聯(lián)并反映在與用例實(shí)現(xiàn)有關(guān)的類圖中;

通信圖中的次序不應(yīng)作為主要的關(guān)注點(diǎn),而且當(dāng)它難以維護(hù)或造成圖的混亂時(shí),可以考慮將其去掉。相反,對(duì)象和每個(gè)特定對(duì)象的需求(對(duì)消息的捕獲)間的關(guān)系(鏈)應(yīng)該是主要的關(guān)注點(diǎn)。順序圖更關(guān)注對(duì)象間消息發(fā)送的先后次序;

通信圖應(yīng)處理所實(shí)現(xiàn)的用例中的所有關(guān)系。例如,如果用例A通過泛化關(guān)系特化出用例B,則實(shí)現(xiàn)用例A的通信圖需要引用用例B的實(shí)現(xiàn)(如引用其通信圖)。順序圖通常只能表示少數(shù)幾個(gè)對(duì)象之間的交互。

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論