




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第9章
面向?qū)ο蠓治?.1分析工作流9.2分析模型9.3確定分析包9.4提取實體類9.5提取邊界類和控制類9.6初始功能模型:考勤系統(tǒng)實例研究9.7分析類9.8初始類圖:考勤系統(tǒng)實例研究9.9描述分析對象間的交互9.10用例實現(xiàn):考勤系統(tǒng)實例研究9.11分析包9.12類圖遞增:考勤系統(tǒng)實例研究9.13測試流與分析工作流中的規(guī)格說明文檔9.14小結(jié)習題9
知識點
分析工作流,分析模型,功能模型,動態(tài)模型,建模技術(shù)。
難點
如何將理論與實踐結(jié)合。
基于工作過程的教學任務
通過本章學習,了解分析工作流;理解分析模型,學習建立分析包、分析類;通過電梯問題實例研究,學習實體類的提取,理解如何提取實體類;掌握分析工作流,學會如何描述分析對象間的交互,如何測試用例;規(guī)劃分析工作,進行面向?qū)ο蠓治觯煌ㄟ^考勤系統(tǒng)實例研究,學習分析工作流,理解分析過程。
統(tǒng)一過程的分析工作流有兩個目的。從需求工作流的角度來看,分析工作流的目的是更深刻地理解需求;從設(shè)計工作流和實現(xiàn)工作流的角度看,分析工作流的目的是進一步描述需求,使設(shè)計和實現(xiàn)更易于進行。在分析階段,項目小組的成員共同努力,理解需求,建立分析模型。分析模型有助于精化需求,并探究系統(tǒng)的內(nèi)部,包括內(nèi)部的共享資源。而且,分析模型提供了更強的表達能力和形式化方法,例如交互圖,還有助于組織需求,并能提供一種可維護性的結(jié)構(gòu),便于應對需求變更和重用。
9.1分
析
工
作
流
捕獲需求要使用客戶的語言,用例提供了這樣的基礎(chǔ)。但是,即使與客戶就系統(tǒng)功能達成了共識,也很可能存在著尚未解決的需求問題。這是由于在捕獲需求過程中使用了直觀但不精確的客戶語言,要弄清楚可能遺漏哪些“未解決的問題”,再來了解一下與客戶有效交流的方法。
(1)用例必須盡量保持彼此獨立。這樣,就不會陷入到有關(guān)用例之間干擾、并發(fā)與沖突的細節(jié)中,在用例間競爭系統(tǒng)內(nèi)部共享資源時,經(jīng)常出現(xiàn)這類情況。例如,“存款”和“取款”用例要訪問同一儲戶的賬戶。當一個參與者混合使用多個可能產(chǎn)生無法預測行為的用例時,就可能產(chǎn)生沖突。例如,當一個電話用戶使用“預置喚醒呼叫”用例后,接著使用“呼入改向”用例去對另一個電話用戶進行電話喚醒呼叫。因此,在需求捕獲階段,用例之間的干擾、并發(fā)與沖突問題可能沒有得到完全解決。
(2)必須用客戶語言描述用例。這樣,在用例說明中就應該主要使用自然語言,但是,僅使用自然語言會大大削弱表達能力。在需求捕獲階段,許多本來可以用更形式化的圖符來精確描述的細節(jié)問題,可能因此得不到解決,或只能模糊地描述。
(3)每個用例的構(gòu)造都是為了構(gòu)成完整且直觀的功能規(guī)格說明。這樣,就需要對用例進行組織以便直觀地反映系統(tǒng)“真實”用例。例如,不能為了消除冗余而將用例設(shè)計得太小、太抽象或太不直觀,盡管能做到,還必須在用例說明的易理解性與可維護性之間進行權(quán)衡。因此,需求間的冗余問題可能無法在需求捕獲期間解決。
由于存在著上述未解決的問題,分析的主要目的就是通過深入分析需求來使問題得以解決,與捕獲需求相比,最主要的差別在于可以用開發(fā)者的語言來描述。
因此,在分析階段更多地探究系統(tǒng)內(nèi)部,從而解決用例間的干擾以及類似的問題(上述第1條);還可以采用更形式化的語言對系統(tǒng)需求中的細節(jié)問題(上述第2條)進行描述,以“精化需求”;另外,可以以易于理解、易于組織、易于修改、易于重用和易于維護的方式來組織需求(上述第3條)。這樣,可以按照不同的詳細程度跟蹤需求的不同描述,并保持彼此間的一致。實際上,在用例模型中的用例和分析模型中的用例實現(xiàn)之間可以互相跟蹤,兩類模型之間的區(qū)別如表9-1所示。
那么,為什么不在設(shè)計和實現(xiàn)系統(tǒng)的同時進行需求分析呢?原因還在于:設(shè)計與實現(xiàn)遠比分析(即精化和組織需求)復雜,需要分開來考慮。在設(shè)計與實現(xiàn)階段,必須構(gòu)造系統(tǒng)并確定其表現(xiàn)形式(包括構(gòu)架),必須對系統(tǒng)如何處理諸如性能和分布等需求做出決定,并回答諸如“如何優(yōu)化使執(zhí)行時間不超過5毫秒?”和“如何在網(wǎng)絡上部署代碼而不會加重網(wǎng)絡的通信負載?”等問題,還有很多其他類似的問題需要處理,例如,如何有效地利用數(shù)據(jù)庫和對象請求代理等已有的構(gòu)件,如何將這些構(gòu)件集成到系統(tǒng)構(gòu)架中,以及如何使用程序設(shè)計語言等,這里不一一列舉可能出現(xiàn)的問題。
最初的細化迭代重點在于分析,分析的焦點如圖8-5所示,有助于建立穩(wěn)定的構(gòu)架,有利于深入理解需求。之后,在細化階段的末期與構(gòu)造階段,構(gòu)架已經(jīng)穩(wěn)定而且需求明確后,重點便應轉(zhuǎn)移到設(shè)計與實現(xiàn)上。
在分析階段,項目小組的成員共同努力,理解需求,建立分析模型,相關(guān)人員與結(jié)果如圖9-1所示。分析模型有助于精化需求,并探究系統(tǒng)的內(nèi)部結(jié)構(gòu),包括其內(nèi)部的共享資源。而且,分析模型提供了更強的表達能力和形式化方法,例如交互圖。分析模型還有助于組織需求,并提供一種可維護性的結(jié)構(gòu),例如具有對需求變化的柔性及重用,這種結(jié)構(gòu)不僅益于需求的維護,而且還可以作為設(shè)計和實現(xiàn)活動的輸入。但是,分析模型是一個抽象的過程,分析模型中提出的結(jié)構(gòu)不可能一直維持下去,需要在設(shè)計與實現(xiàn)期間對其進行處理和折衷,因此,應避免去解決某些問題和處理某些需求,最好是推遲到設(shè)計和實現(xiàn)階段去完成。
圖9-1分析中涉及的工作人員與制品
9.2分析模型
分析模型由代表該模型頂層包的分析系統(tǒng)組成;使用分析包將分析模型組織為更易于管理的若干部分,這些部分代表了對子系統(tǒng)或某一層系統(tǒng)的抽象;分析類代表了對系統(tǒng)設(shè)計中的類或子系統(tǒng)的抽象;在分析模型中,用例是通過分析類及其對象實現(xiàn)的,由分析模型中的各種協(xié)作來表示,標記為用例實現(xiàn)—分析,如圖9-2所示。
統(tǒng)一過程是用例驅(qū)動的。在分析工作流中,用類來描述用例。統(tǒng)一過程包含三種類型的類:實體類、邊界類和控制類。
實體類(EntityClass)用來對持久信息進行建模。就銀行軟件產(chǎn)品來說,類Account是實體類,因為賬戶信息必須保留在軟件產(chǎn)品中。
邊界類(BoundaryClass)用來對軟件產(chǎn)品和參與者之間的交互進行建模。通常邊界類與輸入和輸出相關(guān)聯(lián),例如,在銀行軟件產(chǎn)品中,需要打印用戶賬單。
控制類(ControlClass)用來對復雜的計算和算法進行建模。在銀行軟件產(chǎn)品中,計算利息的算法就是一個控制類。
三種類的UML符號構(gòu)造型(Stereotype)如圖9-3所示,是屬于UML的擴展。
圖9-3表示實體類、邊界類和控制類的UML構(gòu)造型(UML擴展機制)
下面,看一看分析工作流的活動,如圖9-4所示。
圖9-4分析工作流,包括參與的工作人員及其活動
在分析期間,隨著分析模型的演化,構(gòu)架設(shè)計師不斷確定新的分析包、類和公共需求,而構(gòu)件工程師則負責對分析包進行精化和維護,如圖9-5所示。
圖9-5分析的輸入及結(jié)果
9.3確
定
分
析
包
分析包提供了將分析模型組織成更小、可管理的“塊”的方式,可以一開始就確定劃分分析任務的方法,或等到分析模型演化為一個需要分解的大型結(jié)構(gòu)時再來確定。
最初一般基于功能需求和問題域來確定分析包。因為要將功能需求捕獲為用例,所以確定分析包的簡單方法是將一些主要的用例分配給一個具體包,然后在該包中實現(xiàn)相應的功能。下面是將用例分配給具體包的原則。
需要支持具體業(yè)務過程的用例;
需要支持系統(tǒng)的具體參與者的用例;
通過泛化和擴展關(guān)系建立用例的關(guān)聯(lián)。在用例彼此間具有特化或“擴展”關(guān)系時,用例集具有強內(nèi)聚性。
這樣,包會將變化局限于一個業(yè)務過程、一個參與者行為或一個緊密相關(guān)的用例集合中,在早期有助于將用例分配到包中。但是,用例一般不局限于一個包內(nèi),而是跨越幾個包。因此,隨著分析工作的進行,當用例實現(xiàn)為類(可能存在于不同的包中)之間協(xié)作時,就會得到一個更加精化的包結(jié)構(gòu)。
舉例:確定分析包
在Interbank中,應該如何從用例模型中確定分析包呢?用例“支付賬單”、“發(fā)送提醒通知單”和“給買主開單”都參與了同一個“銷售:從訂單到交貨”的業(yè)務過程。因此,可以將它們放到一個分析包中。但是,Interbank應能針對不同客戶的需求提供不同的系統(tǒng)。有些客戶只作為買主使用系統(tǒng),另一些客戶只作為賣主,還有一些客戶既是買主又是賣主。
因此,采取將賣主需要的用例實現(xiàn)與買主需要的用例實現(xiàn)分開的措施,可以將業(yè)務過程“銷售:從訂單到交貨”作為一個分析包的設(shè)想進行調(diào)整來滿足不同客戶的需要,這樣,根據(jù)客戶的需要可以分為兩個分析包:“買主賬單管理”和“賣主賬單管理”,如圖9-6所示。
注意,其他用例也支持業(yè)務過程“銷售:從訂單到交貨”,為了簡化,這里忽略。
圖9-6從用例中確定分析包
9.3.1處理分析包之間的共性
在包間經(jīng)常會存在共性的內(nèi)容。例如,當兩個或更多的分析包共享一個分析類時就會出現(xiàn),處理的方法是找出共享類,把它放到一個單獨的分析包中,或只是放到包的外面,然后讓包依賴這個通用的包或類。
這種共性的共享類很像實體類,可以跟蹤到領(lǐng)域或業(yè)務的實體類。因此,如果領(lǐng)域或業(yè)務的實體類是共享的,就值得研究,可以確定為通用分析包。
舉例:確定通用分析包
下面看看Interbank如何從領(lǐng)域模型中確定通用分析包。領(lǐng)域類“儲戶”和“賬戶”都表示現(xiàn)實世界中重要而復雜的實體,這些類需要復雜信息系統(tǒng)的支持,而且可以與其他更為具體的分析包共享。因而Interbank為每個類創(chuàng)建單獨的“賬戶管理”包和“儲戶管理”包,如圖9-7所示。
注意,“賬戶管理”包和“儲戶管理”包可能會包含很多分析類,例如分別與賬戶管理和儲戶管理有關(guān)的控制類和邊界類。所以,這些包不可能只包含一個或幾個可跟蹤到相應領(lǐng)域的實體類。
圖9-7從領(lǐng)域類中確定通用分析包
9.3.2確定服務包
一般在分析工作的后期、對功能需求有了清晰的理解并且大多數(shù)分析類已經(jīng)存在的時候才確定服務包,同一服務包中的分析類用于相同的服務。
通常按下面的步驟來確定服務包。
為每個可選的服務確定一個服務包,這種服務包是一個定制的單元。
舉例:可選的服務包
大部分使用Interbank的賣主都希望系統(tǒng)具有發(fā)送提醒通知單的服務,這種服務在可選的用例“發(fā)送提醒通知單”中描述。有些賣主希望一旦存在過期賬單就自動發(fā)送提醒通知單,而另一些賣主希望在有過期賬單時先得到通知,而后再決定是否發(fā)送提醒通知單。這里,可以表示為兩種可選的且彼此專用的服務包:“自動發(fā)送提醒通知”用于系統(tǒng)自動發(fā)出提醒通知單,而“人工發(fā)送提醒通知”首先通知賣主,而后由他決定是否與買主聯(lián)系,如圖9-8所示。當賣主不需要提醒通知支持時,交付的系統(tǒng)中就不需要附帶該服務包,這些服務包包含在“賣主賬單管理”包中。
圖9-8“賣主賬單管理”包中的“自動發(fā)送提醒通知”和“人工發(fā)送提醒通知”服務包
為每個可能成為可選的服務確定一個服務包,即使每個客戶都希望得到該服務。因為服務包中包含功能相關(guān)的類,所以會得到一種將大部分變化局限于個別服務包中的包結(jié)構(gòu)。這種準則也可以描述為:為功能相關(guān)的類提供的每個服務確定一個服務包。例如,當出現(xiàn)下述情況時,類A和類B功能上是相關(guān)的。
①?A的變化很可能要求B有所變化;
②刪除A,B就是多余的;
③?A的對象可能通過幾個不同的消息與B的對象頻繁地交互。
舉例:確定封裝功能相關(guān)的類的服務包
“賬戶管理”包包括“賬戶”服務包,當需要轉(zhuǎn)賬和提取事務歷史等活動時可以訪問賬戶。包中還包括“風險管理”服務包,用于估計與某個特定賬戶相關(guān)的風險。這些不同的服務包是公共的,由幾個不同的用例實現(xiàn)使用,如圖9-9所示。
圖9-9“賬戶”服務包和“風險管理”服務包,每個服務包均封裝了功能相關(guān)的類
9.3.3確定分析包間的依賴
如果分析包的內(nèi)容間彼此關(guān)聯(lián),就應該定義分析包間的依賴。其目標是確定相對獨立、低耦合和高內(nèi)聚的包。高內(nèi)聚、低耦合使包更易于維護,這是因為改變一個包中的某些類將主要影響該包中的類。例如,對以下各方面的限制或約束就是常見的特殊需求的例子。
持久性;
分布與并發(fā);
安全性;
容錯;
事務處理。
構(gòu)架設(shè)計師負責確定特殊需求,以便開發(fā)人員能夠使用它們來進行特殊的處理。在某些情況下,特殊需求不能預先確定,只能在對用例實現(xiàn)和分析類進行研究時才能確定。
為支持后續(xù)的設(shè)計和實現(xiàn),應該確定每個特殊需求的關(guān)鍵特征。
舉例:確定特殊需求的關(guān)鍵特征
一個持久性需求具有以下特征:
大小范圍(SizeRange):保持持久性的對象的大小范圍。
容量(Volume):保持持久性的對象的數(shù)目。
持久性時間段(PersistencyPeriod):對象一般需要保持持久性的時間段。
更新頻率(UpdateFrequency):對象的更新頻率。
可靠性(Reliability):諸如對象在硬件或軟件崩潰時是
否能保存下來的可靠性問題。
因此,每個特殊需求的特征應該針對引用特殊需求的類和用例實現(xiàn)來加以限定。
9.4提
取
實
體
類
9.4.1實體類的提取
實體類的提取包括三個迭代和增量執(zhí)行的步驟。
(1)功能建模(FunctionalModeling):給出所有用例的場景,場景是用例的實例。
(2)實體類建模(EntityClassModeling):也稱對象模型。確定實體類及其屬性,然后,確定實體類之間的聯(lián)系和交互行為,并用類圖表示這些信息。
(3)動態(tài)建模(DynamicModeling):確定每個實體類執(zhí)行或?qū)ζ鋱?zhí)行的操作,用狀態(tài)圖、通信圖或順序圖表示這些行為。
像所有迭代增量過程一樣,這三個步驟不需要按順序執(zhí)行。一個模型的變化常常會引起其他兩個模型相應的改變。
為了說明步驟是如何進行的,下面提取經(jīng)典的電梯問題的實體類。
9.4.2面向?qū)ο蠓治觯弘娞輪栴}實例研究
電梯問題的邏輯原理是滿足以下約束條件在m層樓之間移動n部電梯。
(1)每部電梯內(nèi)有m個按鈕,每個按鈕對應一個樓層。當有人按下按鈕時,按鈕變亮并指示電梯到相應的樓層;當電梯到達相應的樓層時,按鈕變暗。
(2)除了一樓和頂樓外,每層樓有兩個按鈕,一個向上,一個向下。按鈕按下時變亮;當電梯到達樓層并往請求方向移動的時候,按鈕變暗。
(3)當電梯沒有請求時,停留在當前樓層,電梯門關(guān)閉。
問題中有兩組按鈕。在n部電梯中,每部電梯內(nèi)有m個按鈕,每個按鈕對應一層,稱之為電梯按鈕;而且,每個樓層有兩個按鈕,一個請求電梯向上,一個請求電梯向下,稱之為樓層按鈕;每個按鈕處于兩個狀態(tài):打開(按鈕變亮)或關(guān)閉(按鈕變暗)。最后,假設(shè)電梯門打開,超時后會自動關(guān)閉。
下面對電梯問題進行用例建模,如圖9-10所示。用戶和電梯之間的交互是,用戶按下電梯按鈕來命令電梯或用戶按下樓層按鈕來請求電梯停在某個樓層,所以有兩個用例:按電梯按鈕和按樓層按鈕。
圖9-10電梯問題案例研究用例圖
9.4.3功能建模:電梯問題實例研究
用例提供整體功能的一般描述,場景是用例的實例,就像對象是類的實例一樣。一般來說,場景有很多,每個場景代表一組特定的交互。
下面,考慮圖9-11的場景,這里包含了上面兩個用例的實例。
圖9-11一個正常場景的第一次迭代
圖9-11描述了一個正常場景,根據(jù)對電梯的理解,發(fā)生在用戶和電梯之間的正常的交互動作。
圖9-11的場景是在仔細地觀察不同用戶與電梯之間的交互后,建立起來的,這需要了解業(yè)務。這19個事件詳細描述了用戶A和電梯系統(tǒng)的兩次交互(事件1和事件6),還有電梯系統(tǒng)各組件執(zhí)行的操作(事件2~5和事件7~19)。三個事件即“用戶A進入電梯”、“用戶B離開電梯”和“用戶A離開電梯”沒有加標號。這里只是注釋,因為,在用戶A、用戶B進入或離開電梯時沒有與電梯的任何組件發(fā)生交互。
下面,圖9-12描述了一個異常場景,當用戶在3樓按下向上的按鈕,但他想去1樓時,所發(fā)生的一類情況。該場景同樣是在觀察了很多電梯里用戶的行為構(gòu)造出來的,因為使用電梯的人有時候會按錯按鈕。
圖9-11和圖9-12的場景,還有其他的場景,都是圖9-10用例的特定實例。OOA小組應該研究足夠多的場景,對要建模的系統(tǒng)行為有一個全面的理解。這些信息會用于實體類建模,以確定實體類。
圖9-12一個異常場景
9.4.4實體類建模:電梯問題實例研究
下面就要提取實體類及其屬性,并用UML類圖表示,這里只確定實體類的屬性。
確定實體類的一種方法是從用例推導實體類,也就是說,開發(fā)人員仔細研究所有場景,包括正常的和異常的,以便找出在用例中起作用的組件。從圖9-11和圖9-12的場景可以看到,候選實體類是電梯按鈕、樓層按鈕、電梯、門和定時器等,這些候選實體類跟在實體類建模期間提取的實際的類是很接近的。一般來說,場景有很多,結(jié)果可能的類也很多,缺乏經(jīng)驗的開發(fā)人員可能傾向于從場景中推導太多的類,這不利于實體類建模,因為刪除一個多余的實體類要比添加一個新的實體類要困難得多。
另一種確定實體類的方法是使用CRC(ClassResponsibilityCollaboration,CRC)職責卡(類—責任—協(xié)作),當開發(fā)人員具備特定領(lǐng)域?qū)I(yè)知識時,該方法很有效。但是,如果開發(fā)人員在應用領(lǐng)域沒有或只有很少經(jīng)驗,那么建議使用名詞提取的方法。
1.名詞提取
對于沒有領(lǐng)域?qū)I(yè)知識的開發(fā)人員,最好使用兩階段名詞提取法,先提取候選實體類,然后進行篩選和細化。
階段1:用一段話描述軟件產(chǎn)品。
舉例:電梯問題描述
電梯里和樓層的按鈕控制一幢m層大樓里的n部電梯的移動。當按下請求電梯停在某一樓層的按鈕時,按鈕變亮;當滿足請求時,按鈕變暗。當一部電梯沒有請求時,停留在當前層,電梯門關(guān)閉。
階段2:識別名詞
先在上面的描述中識別出名詞,它們就是候選實體類。
舉例:電梯問題候選類
電梯里和樓層的按鈕控制一幢m層大樓里的n部電梯的移動。當按下請求電梯停在某一樓層的按鈕時,按鈕變亮;當滿足請求時,按鈕變暗。當一部電梯沒有請求時,停留在當前層,電梯門關(guān)閉。
有7個不同名詞:按鈕、電梯、樓層、移動、大樓、請求和電梯門。其中3個名詞(樓層、大樓和電梯門)在問題邊界外,所以被剔除。剩下名詞中的2個(移動和請求)是抽象名詞。經(jīng)驗法則表明,抽象名詞很少是類,往往是類的屬性,例如,變亮是按鈕的屬性。因此剩下的兩個名詞則為候選實體類:電梯類(Elevator)和按鈕類(Button)。
結(jié)果如圖9-13所示。Button類有布爾類型屬性illuminated(變亮)對圖9-11和圖9-12場景中的事件2、7、9、11和16進行建模。但是,這里有兩種類型的按鈕,所以Button類有兩個子類:ElevatorButton類和FloorButton類。ElevatorButton類和FloorButton類的每個實例與Elevator類的實例關(guān)聯(lián)。后者有布爾屬性doorOpen(電梯門打開)對兩個場景的事件4、8、12、14、17和19進行建模。
圖9-13電梯問題案例研究類圖的第一次迭代
實際上,在電梯中,按鈕不直接與電梯發(fā)生作用。如果決定讓某部電梯響應某個特定的請求,就需要電梯控制器。但是,問題描述中并沒有提到電梯控制器,所以在名詞提取過程中就沒有該實體類。換句話說,這里介紹的技術(shù)為找出候選實體類提供了一個思路,但肯定不能依賴它。
把ElevatorController類添加到圖9-13中,便產(chǎn)生了圖9-14。圖9-14中現(xiàn)在只有一對多關(guān)系,對其建模要比對圖9-13中的多對多關(guān)系建模要容易。在動態(tài)建模之前,先了解另一種實體類建模技術(shù)。
2.CRC卡片—職責卡
類—責任—協(xié)作(CRC)卡片常應用于分析工作流。對每個類,軟件開發(fā)小組填寫一張卡片,包括該類的名稱、功能(責任)和它調(diào)用的一組類以完成其功能(協(xié)作)。
圖9-14電梯問題案例研究類圖的第二次迭代
該方法有多種形式的應用。首先,CRC卡片常包含類的屬性和方法,不是用自然語言所表達的“責任”。其次,該技術(shù)已經(jīng)發(fā)生變化,很多組織不再使用卡片,而是把類名寫在記事帖上,記事帖可以在白板上移動,用它們之間的連線表示協(xié)作關(guān)系。現(xiàn)在,整個過程能夠自動化進行,諸如VisualParadigm等CASE工具就包含了在屏幕上生成和更新CRC卡片的組件。
CRC卡片的優(yōu)點在于:通過小組成員之間的交互可以發(fā)現(xiàn)類中遺漏的或錯誤的字段,不管是屬性還是方法。此外,使用CRC卡片可以描述類之間的關(guān)系。一種做法是在小組成員間分發(fā)卡片,然后小組成員扮演類的責任。一個成員可能會說“我是Date類,我的責任是創(chuàng)建新的日期對象?!绷硪粋€小組成員可能會接著說,“我需要Date類的額外功能,需要把日期轉(zhuǎn)換為一個整數(shù),就是距離1900年1月1日的天數(shù),所以要得到兩個日期之間的天數(shù),然后把兩個對應的整數(shù)相減?!币虼?,扮演CRC卡片的責任,是驗證類圖是否完整和正確的有效手段之一。
如前所述,CRC卡片的不足之處在于:除非小組成員在應用領(lǐng)域有豐富的經(jīng)驗,否則通常達不到識別實體類的目的。另一方面,一旦開發(fā)人員已經(jīng)確定了大多數(shù)的類,并知道了其責任和協(xié)作關(guān)系,那么CRC卡片是完成整個過程并確保其正確的好方法。
9.4.5動態(tài)建模:電梯問題實例研究
動態(tài)建模的目的是描述目標產(chǎn)品的動態(tài)行為,可以生成每個類的狀態(tài)圖或順序圖。首先,考慮ElevatorController類,為了簡便起見,只考慮一部電梯。ElevatorController類的狀態(tài)圖如圖9-15所示。
圖9-15ElevatorController狀態(tài)圖的第一次迭代
狀態(tài)圖包含了狀態(tài)、事件和行為。類的屬性有時稱為狀態(tài)變量,在多數(shù)面向?qū)ο髮崿F(xiàn)中,產(chǎn)品狀態(tài)是由不同組件對象屬性的值決定的,一個事件的發(fā)生導致產(chǎn)品進入其他狀態(tài)。
狀態(tài)、事件和行為分布在狀態(tài)圖中。例如,如果當前狀態(tài)是ElevatorEventLoop并且事件“電梯停止,沒有待定請求”為真,則進入圖9-15中的狀態(tài)GoingIntoWaitState。當進入狀態(tài)GoingIntoWaitState時,執(zhí)行“在超時后關(guān)閉電梯門”操作。
考慮圖9-11場景的第一部分。事件1是“用戶A在2樓按下向上的樓層按鈕”。現(xiàn)在來研究狀態(tài)圖。實心圓表示初始狀態(tài),該狀態(tài)將系統(tǒng)帶入狀態(tài)ElevatorEventLoop。沿著最左邊的垂線,如果按鈕按下時是不亮的,則系統(tǒng)進入狀態(tài)ProcessingNewRequest,點亮按鈕并更新請求集,然后進入狀態(tài)ElevatorEventLoop。
在圖9-11場景中的事件3是電梯到達3樓?;氐綘顟B(tài)圖,考慮電梯接近3樓時將會發(fā)生什么。因為電梯是處在運動中的,所以,進入狀態(tài)DeterminingIfStopRequested,執(zhí)行請求集檢查,因為用戶A已經(jīng)請求電梯停在該樓,當電梯到達時,就進入狀態(tài)StoppingAtFloor。電梯停在3樓,打開電梯門,啟動定時器開始計時。去3樓的電梯按鈕沒有按下,接著,進入狀態(tài)ElevatorEventLoop。
用戶A進入電梯,按下去10樓的電梯按鈕。因此,進入狀態(tài)ProcessingNewRequest,接著,又進入狀態(tài)ElevatorEventLoop。此時電梯已經(jīng)停止,有兩個待定請求,所以下一個狀態(tài)是ClosingElevatorDoorss,電梯門在超時后關(guān)閉。3樓的樓層按鈕已由用戶A按下,所以接下來進入的狀態(tài)是TurningOffFloorButton,關(guān)閉樓層按鈕。接著進入狀態(tài)ProcessingNextRequest,電梯開始向4樓移動。
在討論中,可以發(fā)現(xiàn),上面的狀態(tài)圖是從場景中構(gòu)造出來的,確切地說,場景中的特定事件一般化了。例如,考慮正常場景中的第一個事件“用戶A在3樓按下向上的樓層按鈕”。這個特定事件一般化為按下任意一個按鈕(樓層按鈕或電梯按鈕),這時,有兩種可能,按鈕已經(jīng)是亮的(在這種情況下沒有什么事件發(fā)生),或按鈕是不亮的。
為了對這種事件建模,在圖9-15中給出了ElevatorEventLoop狀態(tài)。通過狀態(tài)圖左上角的事件“按下按鈕時,按鈕已亮”執(zhí)行空操作,對按鈕已亮的情況進行建模。另一種情況,通過標有事件“按下按鈕時,按鈕未亮”的箭頭指向的狀態(tài)ProcessingNewRequest,對按鈕未亮的情況進行建模。
現(xiàn)在考慮場景中的事件3“一部電梯到達3樓”,可推廣到電梯在任意樓層間移動的情形。其他的狀態(tài)圖相對比較簡單,留作練習。
9.4.6測試工作流:電梯問題案例研究
現(xiàn)在,功能、實體類和動態(tài)模型都已經(jīng)建好了,下面要進行測試工作流,以檢查之前完成的分析工作流,可以使用CRC卡片。
相應地,為每個實體類編寫CRC卡片:Button類、ElevatorButton類、FloorButton類、Elevator類和ElevatorController類。圖9-16所描述的ElevatorController類的CRC卡片是從圖9-13的類圖和圖9-15的狀態(tài)圖推導出來的。
確切地說,ElevatorController類的責任是通過列舉出ElevatorController類狀態(tài)圖(圖9-15)中的所有操作而得到的。通過分析圖9-14的類圖,可以確定ElevatorController類的協(xié)作類,也可看到ElevatorButton類、FloorButton類和Elevator類與ElevatorController類之間的交互關(guān)系。
該CRC卡片反映了面向?qū)ο蠓治龅谝淮蔚械膬蓚€主要問題。
(1)修改發(fā)現(xiàn)的問題??紤]責任“打開電梯按鈕”,在面向?qū)ο蠓缎屠?,該命令是不合適的。從責任驅(qū)動設(shè)計的觀點看,ElevatorButton類的對象(實例)負責將自己打開或關(guān)閉。從信息隱藏的觀點來看,ElevatorController類不知道ElevatorButton類如何打開一個按鈕。正確的責任應該是:發(fā)送一條消息給ElevatorButton類,讓其自己打開。圖9-16的責任2~6需要進行類似的調(diào)整。這些調(diào)整反映在圖9-17的ElevatorController類的CRC卡片的第二次迭代中。
(2)忽略某個類?;氐綀D9-17,考慮責任7“打開電梯門并啟動定時器”,狀態(tài)的概念有助于確定某個組件是否需要建模成類。如果要考慮的組件包含某個在實現(xiàn)過程中發(fā)生變化的狀態(tài),那么就很有可能建模成類。很顯然,電梯門包含一個狀態(tài)(開或關(guān)),所以ElevatorDoors應該是一個類。
圖9-16對ElevatorController的CRC卡片的第一次迭代圖9-17對ElevatorController類的CRC卡片的第二次迭代
為什么ElevatorDoors應該是一個類,還有另一個原因,面向?qū)ο蠓缎驮试S狀態(tài)隱藏在對象里以防止非法改變。如果存在某個ElevatorDoors類的對象,打開或關(guān)閉電梯門的唯一的方法是發(fā)送一條消息給ElevatorDoors類的對象。在錯誤的時間打開或關(guān)閉電梯門,可能會導致嚴重的事故。
增加ElevatorDoors類意味著圖9-17的責任7和責任8需要調(diào)整,同樣,從責任1到責任6也需要調(diào)整。即需要發(fā)送消息給ElevatorDoors類的實例,使其打開或關(guān)閉。
還有一個問題,責任7是“打開電梯門并啟動定時器”,該責任必須分解成兩個單獨的責任。當然,必須發(fā)送一條消息給ElevatorDoors類來打開門。但是,定時器是ElevatorController類的一部分,因此啟動定時器是ElevatorController類的責任。ElevatorController類的CRC卡片的第二次迭代(如圖9-18所示)表明該責任的分離已圓滿
完成。
除了圖9-17的CRC卡片反映的兩個主要問題外,ElevatorController類的責任“檢查請求集”和“更新請求集”需要增加屬性requests(請求)到ElevatorController類中。這里,只是簡單地定義requests的類型為requestType,requests的數(shù)據(jù)結(jié)構(gòu)將在設(shè)計工作流中確定。
修改過的類圖如圖9-18所示。由于對類圖進行了調(diào)整,用例圖和狀態(tài)圖也應重新檢查,看其是否需要進行修改。用例圖顯然不用修改。但是,必須重新調(diào)整圖9-15的狀態(tài)圖中的操作以反映圖9-18中的責任(CRC卡片第二次迭代),而非圖9-17中的責任(第一次迭代)。
另外,狀態(tài)圖必須擴展以包含新增的類。圖9-19顯示了圖9-11場景的第二次迭代。
圖9-18電梯問題案例研究類圖的第三次迭代圖9-19電梯問題案例研究的正常場景的第二次迭代
9.5提取邊界類和控制類
與實體類不同,邊界類通常比較容易提取。一般來說,每個輸入屏幕、輸出屏幕和打印報告都可以建模成邊界類。例如,對打印報告建模的邊界類包括所有可能包含在報告里的不同數(shù)據(jù)項和打印報告所需執(zhí)行的不同操作。
通常,控制類同樣很容易提取,每個重要的計算都可以建模成一個控制類。
下面通過提取考勤系統(tǒng)實例研究中的類來說明實體類、邊界類和控制類的提取。圖9-20的用例圖是上一章獲取的需求。
圖9-20考勤系統(tǒng)案例研究用例圖的第2次迭代
9.6初始功能模型:考勤系統(tǒng)實例研究
下面,通過考勤系統(tǒng)來實踐分析過程。前面,已經(jīng)完成了考勤應用程序的需求收集,下一步就是分析需求,將其轉(zhuǎn)換成開發(fā)人員可以理解的語言。這個階段,還不用去考慮特殊的技術(shù),關(guān)心的是該模型的內(nèi)部是如何工作的。
這里,從用例分級開始經(jīng)歷一系列步驟,接著尋找候選的對象以及它們之間的交互,最后詳細地描述這些類。
9.6.1劃分用例等級
每個用例都要根據(jù)其風險、對用戶和構(gòu)架的重要性、對團隊是否有能力開發(fā)等方面劃分等級。一旦用例按這些類別來分類,就可以確定哪個用例的子集是最重要的,并適合在第一個迭代中實現(xiàn)。該過程包括一系列權(quán)衡和妥協(xié)的綜合考慮。例如,一個用例的風險可能很高,就想在第一次選代中實現(xiàn)它,但是,如果開發(fā)團隊對實現(xiàn)該用例完全沒有把握,那么,作為妥協(xié),就應該選擇一個風險較低、容易實現(xiàn)的用例。
1.分級系統(tǒng)
通常,可以將用例的風險、重要性、適用性分成1~5個數(shù)字表示的等級。級別越高,該用例就越適合在第一次或者下一次選代中實現(xiàn)。
前面,考勤應用系統(tǒng)中找到了6個用例,圖9-21顯示了其用例圖,與圖9-20沒有什么不同,只是將名稱用英文標識了而已。可以從風險、重要性以及對當前開發(fā)團隊的合適性等方面來描述每個用例。
圖9-21考勤應用系統(tǒng)的頂層用例圖
1)風險
在考慮用例的風險之前,需要先列出項目的風險清單。以下的風險,對多數(shù)的項目來說都是存在的,可以作為考慮項目風險的出發(fā)點。
無法接受的系統(tǒng)性能;
無法接受的用戶界面;
不確定的進度以及開發(fā)周期;
無法應付新的需求。
經(jīng)過考慮,該系統(tǒng)的用戶界面相對簡單,但也意識到,系統(tǒng)性能很關(guān)鍵,最終用戶可能很忙,不希望由于考勤系統(tǒng)的原因而造成延遲。根據(jù)在以往項目中的經(jīng)驗,過一段時間,相關(guān)人員總是不可避免地要增加系統(tǒng)的規(guī)模,讓一些新的特性無縫地添加到系統(tǒng)中。這樣,將系統(tǒng)風險按如下順序排列,并決定按照這個順序來考慮每個用例。
無法接受的系統(tǒng)性能;
無法應付新的需求;
不確定的進度以及開發(fā)周期;
無法接受的用戶界面。
在按風險分級用例之前,需要有一個描述用例級別的簡單方法??稍儐栭_發(fā)人員這樣的問題:他是否有把握在第一次嘗試中解決某個問題,然后讓他從下面的答案中選擇一個。
當然可以,項目團隊以前解決過這種問題;
沒問題,組織以前解決過這種問題;
可以采用第三方提供的產(chǎn)品、培訓、書籍或其他的技術(shù)資源,但團隊內(nèi)部沒有任何經(jīng)驗;
可能吧,聽說過類似的可以解決的問題;
希望可以,但需要做一些開創(chuàng)性的工作。
在評估用例的時候可以發(fā)現(xiàn),這個簡單的風險“譜”將有助于識別出在下一次迭代中必須考慮的高風險用例。
2)重要性
如果一個用例差不多就是系統(tǒng)的愿景,那它對用戶及構(gòu)架就很重要,一個重要的用例應該能夠體現(xiàn)系統(tǒng)的特性和目標。其他的用例也可能會很重要,但只是扮演支持的角色。例如,如果沒有“AddEmployee”用例,那么考勤系統(tǒng)將無法運行。另一方面,“RecordTime”和“ExportTimeEntries”用例則完全體現(xiàn)了系統(tǒng)的目的。
那么,是否可以這樣衡量用例的重要性:可以詢問開發(fā)人員,如果該用例在本次迭代中忽略掉,或用其他的用例來取代,用戶會怎樣?讓其從下面的答案中選擇一個。
幾乎不會注意到該用例不存在,在沒有它的情況下使用系統(tǒng)不會有什么影響;
會注意到該用例不存在,但是,稍加想象,系統(tǒng)仍然可以很好的使用;
系統(tǒng)的大部分可以獨立于該用例;
系統(tǒng)的一部分可以獨立于該用例;
沒有它,就不可能使用系統(tǒng)。
3)合適性
如果項目組可以只經(jīng)過最少的培訓以及相對短的學習就可以開始開發(fā)某個用例,那么該用例就比較合適。當在機構(gòu)中引入新的技術(shù)、語言和開發(fā)方法時,這兩個標準就特別
重要。
但是,在第一次迭代選擇用例的時候并沒有考慮到技術(shù)選擇,因此很難判斷開發(fā)某個用例時需要學習多少東西。實際上,項目組一般都知道是否需要采用一種新技術(shù),例如,面向?qū)ο箝_發(fā)。而且,一般也知道要采用的語言。因此,可以要求開發(fā)人員描述對方法和技術(shù)的把握有多大,讓其從下面的答案中做出選擇。
團隊絕對需要一段培訓時間才能開發(fā)該用例;
對于該用例來說,團隊可能有足夠的能力,但是,在一次迭代之后,團隊的能力需要有本質(zhì)的提高;
團隊可能有足夠的能力,但是,在一次迭代之后,團隊的能力不需要怎么提高;
不需要很多的培訓,要么是團隊的能力已經(jīng)綽綽有余,要么是該用例相當簡單;
不需要很多的培訓,團隊有足夠的經(jīng)驗,用例也很簡單,手到擒來。
在例子中,假設(shè)開發(fā)團隊經(jīng)驗豐富,絕大多數(shù)的開發(fā)人員至少有一年的面向?qū)ο箝_發(fā)經(jīng)驗,幾乎人人都有至少一年的Java和關(guān)系數(shù)據(jù)庫的開發(fā)經(jīng)驗。
下面,按風險、重要性、合適性來評估用例,找出那些應該在第一次迭代中實現(xiàn)的用例。
2.評估“ExportTimeEntries”用例
“ExportTimeEntries”用例允許管理員導出指定工時條目到格式化的XML文件中。
1)風險
當然,這里包括性能方面的風險。隨著時間的流逝和新用戶的加入,系統(tǒng)的數(shù)據(jù)不斷增多,從中抽取數(shù)據(jù)塊所需的時間也越多,但該任務可以在非高峰時間執(zhí)行。
該用例必須是可擴展的。因為抽取考勤卡條目的標準將會隨著時間而演化并變得更復雜;
該用例比較容易估計,僅僅是找到考勤卡條目,然后將數(shù)據(jù)寫到一個文件中;
用戶界面比較簡單,所以,沒有提交復雜用戶界面的真正風險。
總之,該用例的風險看起來比較低,評為第2級—“沒問題,組織以前解決過這類問題”看起來比較合適。
2)重要性
這是一個非常重要的用例,整個考勤系統(tǒng)的功能就是為各種不同的目標收集并獲取考勤卡條目,評為第5級—“沒有它,系統(tǒng)就不可能使用”比較合適。
3)合適性
該用例相對簡單,團隊可以解決,評為第4級—“不需要很多的經(jīng)驗,要么是團隊的能力已經(jīng)綽綽有余,要么是該用例相當簡單”比較合適。
4)結(jié)論
考慮到重要性,該用例顯然應該在第一次迭代中實現(xiàn)。這有助于同用戶建立信任,并提供重要的構(gòu)架功能。
3.評估“Login”用例
作為執(zhí)行其他更有意義的用例的先決條件,“Login”用例執(zhí)行用戶身份驗證。
1)風險
這里會有性能上的風險,因為,可能會有大量的用戶同時登錄系統(tǒng)。但是,登錄是一個相當簡單的過程,并不涉及很多的數(shù)據(jù)或計算,性能風險較低。
登錄是很容易理解的用例,可擴展性的風險很低;
登錄用例沒有什么進度風險,它很小而且集中;
不存在無法接受的用戶界面風險。
評為第1級—“當然可以,項目組以前解決過這種問題”完全適合該用例的情況。
2)重要性
在最終系統(tǒng)中,如果沒有該用例,系統(tǒng)就完全無法接受。但是,最終用戶完全可以在沒有該用例的情況下評估系統(tǒng)。然而,即使該用例不包括在第一次迭代中,開發(fā)人員還是需要確保其構(gòu)架支持該用例。
評為第2級—“用戶會注意到?jīng)]有該用例,但是,稍加想象,系統(tǒng)仍然可以很好地使用”看起來比較合適。
3)合適性
評為第4級—“不需要很多的培訓,要么是團隊的能力已經(jīng)足以應付,要么是該用例相當簡單”看起來相當合適。
4)結(jié)論
盡管該用例在構(gòu)架上的重要性仍然有所保留,但是,“Login”在第一次迭代時不是特別重要。
4.評估“RecordTime”用例
“RecordTime”用例允許用戶在當前的時間段中輸入工時。
1)風險
性能上的風險是很明顯的,因為在每個時間段的最后幾個小時會有大量的用戶要登記工時。而且,用戶在執(zhí)行這些任務的時候,糟糕的系統(tǒng)性能表現(xiàn)往往會讓他們受不了。例如,雇員可能會心甘情愿地花上15分鐘以等待和下載一個有趣的視頻剪輯,但是,在雜貨店中排上3分鐘的隊,就會感到很惱火。填寫考勤卡一般來說是屬于那類不受歡迎的工作類別,所以必須避免性能問題。
該用例看起來很容易理解,可擴展性的風險很低;
考慮到復雜性和性能需求,對該用例的估計是很復雜的;
用戶界面相當復雜,需要有收費項目代碼選項、條目說明以及一個可編輯的時間條目矩陣。
由于性能需求和用戶界面的復雜性,“RecordTime”用例有很大的風險,評為第3級—“可以采用第三方提供的產(chǎn)品、培訓、書籍或其他的技術(shù)資源,但內(nèi)部沒有任何經(jīng)驗”比較合適。
2)重要性
“RecordTime”用例很重要,體現(xiàn)了考勤系統(tǒng)的意圖。一個不包含該用例的迭代根本讓人無法想象,可以評為第5級—“沒有它,系統(tǒng)就不可能使用”。
3)合適性
復雜性和風險要求在第一次迭代中包含該用例,同時也需要認真評估,看其是否適合開發(fā)團隊,評為第2級—“對該用例來說,團隊可能有足夠的能力,但是,在一次迭代之后,團隊的能力需要有本質(zhì)的提高”看起來比較合適。
4)結(jié)論
顯然,諸多因素使得必須在第一次迭代中包含“RecordTime”用例。但是,由于復雜性,需要在頭兩次迭代中來完成該用例的開發(fā)以滿足相關(guān)人員的需求。例如,在第一次迭代中可以完成用戶界面,而將性能留到下一次迭代。
5.選擇第一次迭代的用例
對于一個有開發(fā)經(jīng)驗的團隊,就可以在風險和重要性的基礎(chǔ)上確定第一次迭代的用例,上面只是分析了關(guān)鍵用例,其他的省略了?!癛ecordTime”和“ExportTimeEntries”肯定應該屬于第一次迭代,“CreateEmployee”、“CreateChargeCode”和“ChangePassword”可以推遲實現(xiàn),“Login”也可以推遲,但是可以將它包含進來,使第一次迭代更真實。
將所有對構(gòu)架重要的用例都放在第一次迭代中,在這次迭代完成后,相關(guān)人員就可以得到關(guān)于系統(tǒng)的清晰的印象,而且開發(fā)者可以通過這幾個關(guān)鍵用例來確保解決方案的完
整性。
在選定了第一次迭代的用例之后,下面要完成剩下的分析步驟。
9.6.2尋找候選對象
這一步,開發(fā)人員要找出提供用例功能的對象,可以將對象劃分為三種類型:實體類、邊界類和控制類,這樣,可以大大簡化該過程。
在尋找對象的時候,很重要的一點,就是要限制每個對象的責任,并為每個對象以及對象的每個方法采用一致的命名。
由于剛剛開始進行分析,所以不會花很多的時間來確定對象之間的關(guān)系。在后面的步驟中,這些關(guān)系將會得到澄清。因此,要盡量保持簡單,不要試圖去完成一個完美的草圖。
1.尋找實體對象
對每個用例,搜索每個事件流來尋找名詞、數(shù)據(jù)和行為。名詞將會成為實體對象,數(shù)據(jù)則可能會是對象的屬性,而行為將分配給一個或多個對象。每個用例中的名詞先單獨考慮,然后再綜合考慮。
1)“RecordTime”用例
瀏覽一下該用例的正常事件流,關(guān)注下面的對象和數(shù)據(jù)。
雇員查看當前時間段之前輸入的數(shù)據(jù);
雇員從已有的支付號碼中選擇一個,這些收費代碼按客戶和項目組織;
雇員為當前的時間段選擇日期;
雇員輸入以正整數(shù)表示的時間數(shù);
在視圖中顯示數(shù)據(jù),在以后的視圖中可以看到該數(shù)據(jù)。
下面是在第一個可選事件流——雇員編輯已有的數(shù)據(jù)中需要強調(diào)的部分。
雇員看到當前時間段之前輸入的數(shù)據(jù);
雇員選擇一個已有的條目;
雇員修改工時和/或支付號碼;
在視圖中更新信息,在以后的視圖中可以看到。
以下則是在第二個可選事件流——提交考勤卡作為結(jié)束中需要強調(diào)的部分。
雇員看到當前時間段之前輸入的數(shù)據(jù);
雇員選擇提交考勤卡;
系統(tǒng)要求雇員確認提交,提醒雇員將不能再編輯這些條目;
提交考勤卡,不能再進行編輯。
在剩下的事件流中沒有再引入新的信息,下面,列出名詞列表,然后逐個判斷,剔除那些不需要的和重復的實體對象,同時,識別那些不適合作為一個獨立的對象、而應該是其他對象屬性的名詞。
收費代碼。
支付號碼。顯然,這兩個詞是同義詞,由于在其他文檔中,收費代碼使用更普遍,所以丟棄支付號碼,選擇收費代碼作為一類實體對象。
客戶??蛻艨雌饋硎且活悓嶓w對象。
日期。日期似乎不是一個獨立的對象類型,相反,更像是對象中的數(shù)據(jù)。
雇員。雇員應該是一個獨立的實體對象。
已有的條目。考勤卡中的一個條目可能是一個保存日期的對象,姑且認為它是一類實體對象。
時間數(shù)。
工時。這兩個是同義詞,但是,工時更有意義,所以丟棄時間數(shù)。工時成為一個剛發(fā)現(xiàn)的條目對象的數(shù)據(jù)。
以前輸入的數(shù)據(jù)。與條目對象相同,所以丟棄掉。
項目。項目是一類實體對象。
考勤卡??记诳ㄊ且活悓嶓w對象。
時間段。時間段描述一個考勤卡,所以是考勤卡對象的數(shù)據(jù)。
視圖。視圖是邊界對象,所以排除掉。
這樣,“RecordTime”用例就分析完畢,實體對象有:收費項目代碼、客戶、雇員、已有的條目、工時、項目和考勤卡。
2)“ExportTimeEntries”用例
瀏覽一下“ExportTimeEntries”用例的正常事件流,關(guān)注下面的候選對象和數(shù)據(jù)。
管理員選擇一段日期;
管理員選擇一些或所有的客戶;
管理員選擇一些或所有的雇員;
管理員選擇目標文件;
數(shù)據(jù)以XML格式導出到文件中,過程結(jié)束后通知管理員。
下一步,列出名詞列表,然后逐個判斷。
管理員。管理員應該是一個實體對象。
客戶。客戶已經(jīng)識別為一類實體對象了。
?XML格式。這個是對輸出文件的描述而不是實體對象。
數(shù)據(jù)。這里的數(shù)據(jù)指的是一組考勤卡中的一組條目,已經(jīng)是實體對象了,沒有必要再增加新對象。
雇員。雇員是已經(jīng)識別出來的對象。
一段日期。一段日期是在另一個對象中的數(shù)據(jù)。增加一個新的實體對象——輸出請求,雖然它并沒有在事件流中出現(xiàn)。
目標文件。這個顯然是作為輸出請求的一個數(shù)據(jù)。
這樣,在該用例中,得到兩個新對象:管理員和輸出請求。接下來看看下一個用例。
3)“Login”用例
瀏覽一下“Login”用例的正常事件流,關(guān)注下面的候選對象和數(shù)據(jù)。
管理員或雇員輸入用戶名和密碼。
驗證用戶是管理員還是雇員,用戶在登錄的時候并沒有選擇身份,是由系統(tǒng)根據(jù)用戶名確定的。
現(xiàn)在列出名詞列表,然后逐個判斷。
管理員。管理員已經(jīng)識別為一類實體對象了。
雇員。雇員已經(jīng)識別為一類實體對象了。
密碼。密碼應該是管理員對象或雇員對象的數(shù)據(jù)。
用戶。用戶應該是管理員或雇員的一個更通用的類別。
用戶名。用戶名應該是管理員對象或雇員對象的數(shù)據(jù)。
評估完該用例,沒有得到新的對象。
4)合并實體對象
得到下面的實體對象表。
管理員、收費代碼、客戶、雇員、已有的條目、工時、項目、考勤卡。
這里只有兩個實體對象看起來比較相似,即管理員和雇員,都是用戶類,—個有管理員權(quán)限而另一個沒有,所以可以刪除這兩個類并增加用戶類。
圖9-22所示的類圖顯示了這些實體對象。
圖9-22實體類
2.尋找邊界對象
下一步是識別邊界對象。在分析階段,尋找邊界對象的規(guī)則是:每一對參與者、用例對應一個邊界對象。
對“ExportTimeEntries”用例,有一個作為管理員和系統(tǒng)接口的邊界對象,就得到了一個作為系統(tǒng)和外部支付系統(tǒng)接口的邊界對象。
對“RecordTime”用例,根據(jù)這個規(guī)則可以找到兩個邊界對象:一個是作為管理員和系統(tǒng)的接口,另一個是普通雇員和系統(tǒng)的接口。盡管前面將管理員和雇員合并為一個實體對象,但是,邊界對象是由人們或外部系統(tǒng)如何使用系統(tǒng)來決定的,而不是由它們在系統(tǒng)中是如何表示來確定。
對“Login”用例,根據(jù)這個規(guī)則可以找到兩個邊界對象:一個是作為管理員和系統(tǒng)的接口,而另一個是普通雇員和系統(tǒng)的接口。
用標準的命名規(guī)范可以簡化該過程,可以用UI作為用戶界面對象的后綴,用SystemInterface作為系統(tǒng)接口的后綴。如果有多個參與者觸發(fā)一個用例,邊界對象就得分別命名。應用這些規(guī)則,就得到如圖9-23所示的邊界類。
3.尋找控制類
在分析過程中,尋找控制類的規(guī)則是每個用例分配類控制對象。每個控制對象為一個用例封裝工作流,這樣實體對象就可以保持集中,而由控制對象向邊界對象提供簡單的接口。
在為控制對象命名時,要保持簡潔,可以選擇一個合理的后綴,如Workflow,這樣做有利于系統(tǒng)的理解。在很多時候,只要在用例名后加一個Workflow就可以了。在命名風格上,并沒有什么限制,簡單和一致才是最重要的。
對“ExportTimeEntries”用例,根據(jù)規(guī)則可以得到一個叫做“ExportTimeEntriesWorkflow”的控制類;
對“RecordTime”用例,根據(jù)規(guī)則可以得到一個叫做“RecordTimeWorkflow”的控制類;
對“Login”用例,根據(jù)規(guī)則可以得到一個叫做“LoginWorkflow”的控制類。
圖9-24顯示這些控制類。
在很多情況下,了解實體對象如何使用更有意義,因此,進入下一步,描述對象交互。
圖9-24控制類
9.7分
析
類
下面是分析一個類的目的(如圖9-25所示)。
依據(jù)分析類在用例實現(xiàn)中的角色來確定和維護它的職責;
確定和維護分析類的屬性及其關(guān)系;
捕獲分析類實現(xiàn)的特殊需求。圖9-25分析類的輸入和結(jié)果
9.7.1確定職責
組合一個類在不同用例實現(xiàn)中充當?shù)慕巧梢詤R集該類的職責,研究類圖和交互圖可以確定類參與的用例實現(xiàn)。還要記住,對于類的每個用例實現(xiàn)的需求,有時是在用例實現(xiàn)的事件流分析中用文本進行描述的。
舉例:類的角色
“賬單”對象是在用例“給買主開單”中創(chuàng)建的。賣主執(zhí)行該用例來請求買主支付訂單(訂單是在用例“訂購貨物或服務”中創(chuàng)建的)。在這個用例期間,賬單傳遞給買主,隨后由他決定支付賬單。
“支付”在“支付賬單”用例中實現(xiàn),此時“支付調(diào)度程序”對象調(diào)度“賬單”對象來確定支付日期。之后,支付賬單,并關(guān)閉“賬單”對象。
需要注意,參與用例“給買主開單”和用例“支付賬單”的是“賬單”對象的同一個實例。
有多種方式可以匯集類的職責。一種簡單的方法是每次從一個角色中抽取出職責,再附加上每次基于一個用例實現(xiàn)得到的補充職責或修改現(xiàn)有的職責。
舉例:類的職責
“支付調(diào)度程序”類有以下職責:
創(chuàng)建一個支付請求;
跟蹤已確定支付時間的支付,當實施支付或取消支付時發(fā)送一條通知;
在規(guī)定的支付日期啟動金額的轉(zhuǎn)賬;
當賬單已確定了支付日期和已經(jīng)支付(即關(guān)閉)時,通知“賬單”對象。
9.7.2確定屬性
屬性詳細說明了分析類的特性,一般由類的職責直接或間接決定。在確定屬性時,應記住下面常識性的指南。
屬性的名稱應是一個名詞;
記住,屬性的類型在分析階段應該是概念上的,如果可能的話,不應受到實現(xiàn)環(huán)境的限制。例如,分析階段中“數(shù)量”可能是一種合適的類型,但在設(shè)計階段,它所對應的類型應為“整型”;
在選擇一種屬性類型時,盡量重用已存在的類型;
一個簡單的屬性實例不能由多個分析對象共享。如果需要這樣,屬性要在自己的類中進行定義;
如果一個分析類由于自己的屬性變得過于復雜而難以理解,可以將其中的一些屬性分成它們自己的類;
實體類的屬性通常很明顯。如果一個實體類可以跟蹤到一個領(lǐng)域類或一個業(yè)務實體類,這些類的屬性可作為重要的輸入;
與由人充當?shù)膮⑴c者進行交互的邊界類,其屬性經(jīng)常表示由該參與者所操作的信息項,例如帶標記的文本域;
與由系統(tǒng)充當?shù)膮⑴c者進行交互的邊界類,其屬性經(jīng)常表示通信接口的特性;
控制類由于其生命周期短暫,因此很少具有屬性。然而在用例實現(xiàn)期間,控制類可能會有代表聚集或派生價值的屬性;
有時并不需要形式化的屬性。相反,對由分析類處理的特性進行簡單說明就足夠了,而且還可以放到該類的責任描述中;
如果一個類具有很多屬性或復雜屬性時,可以在一個只顯示屬性欄的單獨的類圖中加以說明。
9.7.3確定關(guān)聯(lián)和聚合
分析對象通過通信圖中的鏈進行交互,這些鏈一般是分析對象的相應類之間關(guān)聯(lián)的實例。因此,構(gòu)件工程師應該研究通信圖中的鏈以便確定需要哪些關(guān)聯(lián),這些鏈表明對象間的引用和聚合。
類之間關(guān)系的數(shù)量應盡量少。它主要不是指現(xiàn)實世界中那種能作為聚合或關(guān)聯(lián)來建模的關(guān)系,而是指為了響應各種用例實現(xiàn)的需求而必須存在的關(guān)系。分析階段的重點不在于通過聚合或關(guān)聯(lián)來對最佳搜索路徑建模,這項工作最好放在設(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)
賬單是對一張或多張訂單的支付請求(如圖9-26所示),可以表示為一個帶有“1..*”多重性的關(guān)聯(lián)(一般至少有一張訂單與賬單關(guān)聯(lián))和角色名稱“支付訂單”。
圖9-26賬單與訂單之間的一對多關(guān)聯(lián)
當對象表示下面的事物時應該使用聚合。
實際中相互包容的概念,如汽車包含駕駛員和乘客;
相互間存在組成關(guān)系的概念,如汽車由發(fā)動機和車輪等部件組成;
構(gòu)成對象的概念性集合的概念,如家庭由父親、母親和孩子組成。
9.7.4確定泛化
在分析階段,從幾個不同的分析類中抽取共享和公用的行為時應該使用泛化,泛化應處于較高的概念層,以使分析模型易于理解。
舉例:確定泛化
“賬單”類和“訂單”類具有相似的職責,二者都是對象“交易”的特化,如圖9-27所示。
在設(shè)計階段,應該對泛化關(guān)系進行調(diào)整,以便更好地適應所選的實現(xiàn)環(huán)境,如程序設(shè)計語言泛化有可能消失,而變?yōu)橛善渌P(guān)系(如關(guān)聯(lián))來實現(xiàn)。
圖9-27“交易”對象是“賬單”和“訂單”的泛化
9.7.5捕獲特殊需求
現(xiàn)在,將捕獲在分析階段中確定的、但應該在設(shè)計和實現(xiàn)階段中進行處理的分析類的所有需求(如非功能性需求)。在捕獲這些需求時,務必要研究用例實現(xiàn)的特殊需求,因為它們可能包含了與分析類有關(guān)的補充(非功能性的)需求。
舉例:捕獲與分析類有關(guān)的特殊需求
下面是對“賬單”類的持久性需求的特征限定。
大小范圍(SizeRange):每個對象2K至1024K字節(jié)。
容量(Volume):最大為100000。
更新頻率(UpdateFrequency)。
創(chuàng)建/刪除:1000次/天。
更新:30次/小時。
讀取:訪問1次/小時。
在捕獲這些需求時,應該盡可能參照已由構(gòu)架設(shè)計師確定的、公用的特殊需求。
9.8初始類圖:考勤系統(tǒng)實例研究
現(xiàn)在,要確定類之間的關(guān)系,這些關(guān)系是支持事件流中對象交互所必需的,可以通過類圖來完成。這意味著,同一個用例的幾個順序圖會共享一個類圖。
通過簡單的工作,就可以確定一個關(guān)系是否必要。從一個對象發(fā)往另一個對象的每條消息都需要一個從發(fā)送對象類到接收對象類之間的關(guān)系。
如果一個發(fā)送對象創(chuàng)建一個接收對象,使用它,然后拋棄;或從方法的參數(shù)中獲取接收對象、使用它但不保存,就是一種依賴關(guān)系。在分析階段,這個關(guān)系可能比較難確定,因為這里沒有方法參數(shù)。因此,這種關(guān)系的確定在分析階段并不重要。
9.8.1尋找“Login”中的關(guān)系
在“Login”用例的正常事件流的順序圖中按順序?qū)ふ谊P(guān)系。EmployeeLoginUI對象調(diào)用LoginWorkflow對象中的validateLogin()方法,這意味著從EmployeeLoginUI類到LoginWorkflow類之間存在關(guān)系。從LoginWorkflow類到User類和UserLocator類之間也存在關(guān)系。返回值并不表明關(guān)系,因為對象并不需要通過引用來返回消息。
在確定關(guān)系的方向之后,來考慮每個關(guān)系的類型。首先,對EmployeeLoginUI對象,保存對LoginWorkflow對象的引用似乎是沒必要的,然而,看一下“Login”用例的活動圖,可以看到,EmployeeLoginUI允許用戶重新輸入姓名和密碼。這使得EmployeeLoginUI對象有必要保存對LoginWorkflow對象的引用。所以,這是一個關(guān)聯(lián)關(guān)系。
同樣的邏輯存在于LoginWorkflow對象和UserLocator對象之間的關(guān)系。LoginWorkflow對象需要保存一個引用來處理后續(xù)用戶的登錄,所以這是一個關(guān)聯(lián)關(guān)系。
LoginWorkflow對象不需要保存對User對象的引用,因為LoginWorkflow每一次都要重新尋找User對象,所以這是一個依賴關(guān)系。圖9-28顯示了這些關(guān)系。
圖9-28參與“Login”用例的類
9.8.2尋找“RecordTime”中的關(guān)系
圖9-29顯示了這些關(guān)系。
RecordTimeUI對象使用RecordTimeWorkflow對象,后者又使用了User對象以及TimeCard對象。RecordTimeUI對象保存對RecodTimeWorkflow對象的引用,用它來更新條目,所以這是一個關(guān)聯(lián)關(guān)系。
RecordTimeWorkflow對象保存對User對象的引用,在RecordTimeWorkflow對象提交一個舊的考勤卡并使用新的考勤卡來替換時要使用到User對象,所以這是一個關(guān)聯(lián)關(guān)系。
圖9-29參與“RecordTime”用例的類
RecordTimeWorkflow對象保存對TimeCard對象的引用。在RecordTimeWorkflow對象為TimeCard對象設(shè)置條目的時候要用到TimeCard對象,所以這是一個關(guān)聯(lián)關(guān)系。
9.8.3尋找“ExportTimeEntries”中的關(guān)系
ExportEntriesUI對象要用到ClientLocator對象和UserLocator對象,也要用到ExportEntriesWorkflow對象。ExportEntriesWorkflow對象使用EntryLocator對象,BillingSystemInterface對象以及大量的Entry對象。沒有對象重用,所以,這里所有的關(guān)系都可以當做依賴關(guān)系。
需要注意的一點是,ExportEntriesUI對象直接與ClientLocator和UserLocator對象交互,而不是通過控制對象。圖9-30顯示了這些關(guān)系。
圖9-30參與“ExportTimeEntries”用例的類
9.9描述分析對象間的交互
當有了實現(xiàn)用例所需要的分析類的框架之后,就需要描述分析對象間如何進行交互,可以使用順序圖、通信圖或活動圖來實現(xiàn)。順序圖將交互關(guān)系表示為一個二維圖??v向是時間軸,時間沿豎線向下延伸。橫向代表了協(xié)作中各獨立對象的類元角色,類元角色用生命線表示。當對象存在時,角色用一條虛線表示,當對象的過程處于激活狀態(tài)時,生命線是一條雙道線。
通信圖包含了參與的參與者實例、分析對象以及它們的鏈接。如果該用例具有不同的或獨特的流或子流,通常值得為每個流創(chuàng)建一幅通信圖,這使用例實現(xiàn)更清晰,而且也能夠提取出表示通用和可重用的交互關(guān)系的通信圖。順序圖和通信圖在語義上是等價的,可以互相轉(zhuǎn)換,但兩者的側(cè)重點不同,順序圖關(guān)注交互的時間次序,通信圖關(guān)注對象間的交互和連接。
順序圖詳細而直觀地表現(xiàn)了一組相互協(xié)作的對象在執(zhí)行一個(或幾個)用例時的行為依賴關(guān)系,以及服務和消息的時序關(guān)系。類圖對對象之間的消息(交互情況)表達得不夠詳細,詳細說明對消息的表達雖然詳細,但不夠直觀。順序圖既詳細又直觀,但一般只能表示少數(shù)幾個對象之間的交互。
順序圖可以幫助分析員對照檢查每個用例中描述的用戶需求,是否已經(jīng)落實到一些對象中去實現(xiàn);可以提醒分析員去補充遺漏的對象類或服務;可以幫助分析員發(fā)現(xiàn)哪些對象是主動對象;通過對一個特定的對象群體的動態(tài)建模,深刻地理解對象之間的交互。
創(chuàng)建交互圖是從用例流的初期開始的,然后一次一步地通過用例流并決定實現(xiàn)該步需要哪些分析對象與參與者實例進行交互。通??梢院茏匀坏卮_定對象在用例實現(xiàn)的交互序列中所處的位置。對于交互圖應注意下面幾點。
可以從一個參與者實例向一個邊界對象發(fā)送一個消息來引入用例;
每個在先前步驟中確定的分析類應至少有一個分析對象參與某個交互。否則,由于該分析類不參加任何用例實現(xiàn),就是多余的;
不要將消息指定給操作,因為并沒有為分析類確定操作。消息應該表示出引用對象在與被引用對象交互時的意圖。這種“意圖”是接收對象的職責的根據(jù),甚至可能成為該職責的名稱;
通信圖中鏈接一般應是分析類間關(guān)聯(lián)的實例,順序圖不關(guān)注鏈接。這可以概括出所有顯見的關(guān)聯(lián)并反映在與用例實現(xiàn)有關(guān)的類圖中;
通信圖中的次序不應作為主要的關(guān)注點,而且當它難以維護或造成圖的混亂時,可以考慮將其去掉。相反,對象和每個特定對象的需求(對消息的捕獲)間的關(guān)系(鏈)應該是主要的關(guān)注點。順序圖更關(guān)注對象間消息發(fā)送的先后次序;
通信圖應處理所實現(xiàn)的用例中的所有關(guān)系。例如,如果用例A通過泛化關(guān)系特化出用例B,則實現(xiàn)用例A的通信圖需要引用用例B的實現(xiàn)(如引用其通信圖)。順序圖通常只能表示少數(shù)幾個對象之間的交互。
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 常州工學院《食品安全與衛(wèi)生實驗》2024-2025學年第一學期期末試卷
- 淮北師范大學《公共體育3》2024-2025學年第一學期期末試卷
- 安徽交通職業(yè)技術(shù)學院《Hadoop技術(shù)》2024-2025學年第一學期期末試卷
- 2024年中級注安《化工實務》考試模擬試題及答案
- 健康管理師健康管理概論試題及答案
- 長春電子科技學院《西方社會思想史》2024-2025學年第一學期期末試卷
- 新疆農(nóng)業(yè)大學科學技術(shù)學院《金文與摩崖隸書(2)》2024-2025學年第一學期期末試卷
- 鍋爐面試題目及答案
- 武漢工程職業(yè)技術(shù)學院《Spak大數(shù)據(jù)分析》2024-2025學年第一學期期末試卷
- 2025年全國押運員試題及答案
- 2025年甘肅社會化工會工作者招聘考試(公共基礎(chǔ)知識)模擬試題及答案
- 《心系國防 強國有我》 課件-2024-2025學年高一上學期開學第一課國防教育主題班會
- 妊娠患者非產(chǎn)科手術(shù)麻醉
- YY/T 0461-2003麻醉機和呼吸機用呼吸管路
- GB/T 7064-2017隱極同步發(fā)電機技術(shù)要求
- 例談小組合作學習在小學英語教學中的有效開展(講座)課件
- 煤礦安全規(guī)程2022
- 污水處理廠安全風險清單
- 營造林工試題庫技師1
- 特種設(shè)備安全管理制度特種設(shè)備安全操作規(guī)程
- 連續(xù)安全技術(shù)交底8篇-1
評論
0/150
提交評論