軟件工程學(xué)-面向?qū)ο笤O(shè)計(jì)_第1頁
軟件工程學(xué)-面向?qū)ο笤O(shè)計(jì)_第2頁
軟件工程學(xué)-面向?qū)ο笤O(shè)計(jì)_第3頁
軟件工程學(xué)-面向?qū)ο笤O(shè)計(jì)_第4頁
軟件工程學(xué)-面向?qū)ο笤O(shè)計(jì)_第5頁
已閱讀5頁,還剩146頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第11章面向?qū)ο笤O(shè)計(jì)11.1面向?qū)ο笤O(shè)計(jì)的準(zhǔn)則11.2啟發(fā)規(guī)則11.3軟件重用11.4系統(tǒng)分解11.5設(shè)計(jì)問題域子系統(tǒng)11.6設(shè)計(jì)人機(jī)交互子系統(tǒng)11.7設(shè)計(jì)任務(wù)管理子系統(tǒng)11.8設(shè)計(jì)數(shù)據(jù)管理子系統(tǒng)11.9設(shè)計(jì)類中的服務(wù)11.10設(shè)計(jì)關(guān)聯(lián)11.11設(shè)計(jì)優(yōu)化11.12小結(jié)習(xí)題如前所述,分析是提取和整理用戶需求,并建立問題域精確模型的過程。設(shè)計(jì)則是把分析階段得到的需求轉(zhuǎn)變成符合成本和質(zhì)量要求的、抽象的系統(tǒng)實(shí)現(xiàn)方案的過程。從面向?qū)ο蠓治龅矫嫦驅(qū)ο笤O(shè)計(jì)(OOD),是一個(gè)逐漸擴(kuò)充模型的過程?;蛘哒f,面向?qū)ο笤O(shè)計(jì)就是用面向?qū)ο笥^點(diǎn)建立求解域模型的過程。盡管分析和設(shè)計(jì)的定義有明顯區(qū)別,但是在實(shí)際的軟件開發(fā)過程中二者的界限是模糊的。許多分析結(jié)果可以直接映射成設(shè)計(jì)結(jié)果,而在設(shè)計(jì)過程中又往往會(huì)加深和補(bǔ)充對系統(tǒng)需求的理解,從而進(jìn)一步完善分析結(jié)果。因此,分析和設(shè)計(jì)活動(dòng)是一個(gè)多次反復(fù)迭代的過程。面向?qū)ο蠓椒▽W(xué)在概念和表示方法上的一致性,保證了在各項(xiàng)開發(fā)活動(dòng)之間的平滑(無縫)過渡,領(lǐng)域?qū)<液烷_發(fā)人員能夠比較容易地跟蹤整個(gè)系統(tǒng)開發(fā)過程,這是面向?qū)ο蠓椒ㄅc傳統(tǒng)方法比較起來所具有的一大優(yōu)勢。生命周期方法學(xué)把設(shè)計(jì)進(jìn)一步劃分成總體設(shè)計(jì)和詳細(xì)設(shè)計(jì)兩個(gè)階段,類似地,也可以把面向?qū)ο笤O(shè)計(jì)再細(xì)分為系統(tǒng)設(shè)計(jì)和對象設(shè)計(jì)。系統(tǒng)設(shè)計(jì)確定實(shí)現(xiàn)系統(tǒng)的策略和目標(biāo)系統(tǒng)的高層結(jié)構(gòu)。對象設(shè)計(jì)確定解空間中的類、關(guān)聯(lián)、接口形式及實(shí)現(xiàn)服務(wù)的算法。系統(tǒng)設(shè)計(jì)與對象設(shè)計(jì)之間的界限,比分析與設(shè)計(jì)之間的界限更模糊,本書不再對它們加以區(qū)分。本章首先講述為獲得優(yōu)秀設(shè)計(jì)結(jié)果應(yīng)該遵循的準(zhǔn)則,然后具體講述面向?qū)ο笤O(shè)計(jì)的任務(wù)和方法。所謂優(yōu)秀設(shè)計(jì),就是權(quán)衡了各種因素,從而使得系統(tǒng)在其整個(gè)生命周期中的總開銷最小的設(shè)計(jì)。對大多數(shù)軟件系統(tǒng)而言,60%以上的軟件費(fèi)用都用于軟件維護(hù),因此,優(yōu)秀軟件設(shè)計(jì)的一個(gè)主要特點(diǎn)就是容易維護(hù)。本書第5章曾經(jīng)講述了指導(dǎo)軟件設(shè)計(jì)的幾條基本原理,這些原理在進(jìn)行面向?qū)ο笤O(shè)計(jì)時(shí)仍然成立,但是增加了一些與面向?qū)ο蠓椒芮邢嚓P(guān)的新特點(diǎn),從而具體化為下列的面向?qū)ο笤O(shè)計(jì)準(zhǔn)則。11.1面向?qū)ο笤O(shè)計(jì)的準(zhǔn)則1.模塊化面向?qū)ο筌浖_發(fā)模式,很自然地支持了把系統(tǒng)分解成模塊的設(shè)計(jì)原理:對象就是模塊。它是把數(shù)據(jù)結(jié)構(gòu)和操作這些數(shù)據(jù)的方法緊密地結(jié)合在一起所構(gòu)成的模塊。2.抽象面向?qū)ο蠓椒ú粌H支持過程抽象,而且支持?jǐn)?shù)據(jù)抽象。類實(shí)際上是一種抽象數(shù)據(jù)類型,它對外開放的公共接口構(gòu)成了類的規(guī)格說明(即協(xié)議),這種接口規(guī)定了外界可以使用的合法操作符,利用這些操作符可以對類實(shí)例中包含的數(shù)據(jù)進(jìn)行操作。使用者無須知道這些操作符的實(shí)現(xiàn)算法和類中數(shù)據(jù)元素的具體表示方法,就可以通過這些操作符使用類中定義的數(shù)據(jù)。通常把這類抽象稱為規(guī)格說明抽象。此外,某些面向?qū)ο蟮某绦蛟O(shè)計(jì)語言還支持參數(shù)化抽象。所謂參數(shù)化抽象,是指當(dāng)描述類的規(guī)格說明時(shí)并不具體指定所要操作的數(shù)據(jù)類型,而是把數(shù)據(jù)類型作為參數(shù)。這使得類的抽象程度更高,應(yīng)用范圍更廣,可重用性更高。例如,C++語言提供的“模板”機(jī)制就是一種參數(shù)化抽象機(jī)制。3.信息隱藏在面向?qū)ο蠓椒ㄖ?,信息隱藏通過對象的封裝性實(shí)現(xiàn):類結(jié)構(gòu)分離了接口與實(shí)現(xiàn),從而支持了信息隱藏。對于類的用戶來說,屬性的表示方法和操作的實(shí)現(xiàn)算法都應(yīng)該是隱藏的。4.弱耦合耦合指一個(gè)軟件結(jié)構(gòu)內(nèi)不同模塊之間互連的緊密程度。在面向?qū)ο蠓椒ㄖ?,對象是最基本的模塊,因此,耦合主要指不同對象之間相互關(guān)聯(lián)的緊密程度。弱耦合是優(yōu)秀設(shè)計(jì)的一個(gè)重要標(biāo)準(zhǔn),因?yàn)檫@有助于使得系統(tǒng)中某一部分的變化對其他部分的影響降到最低程度。在理想情況下,對某一部分的理解、測試或修改,無須涉及系統(tǒng)的其他部分。如果一類對象過多地依賴其他類對象來完成自己的工作,則不僅給理解、測試或修改這個(gè)類帶來很大困難,而且還將大大降低該類的可重用性和可移植性。顯然,類之間的這種相互依賴關(guān)系是緊耦合的。當(dāng)然,對象不可能是完全孤立的,當(dāng)兩個(gè)對象必須相互聯(lián)系相互依賴時(shí),應(yīng)該通過類的協(xié)議(即公共接口)實(shí)現(xiàn)耦合,而不應(yīng)該依賴于類的具體實(shí)現(xiàn)細(xì)節(jié)。一般說來,對象之間的耦合可分為兩大類,下面分別討論這兩類耦合:(1)交互耦合如果對象之間的耦合通過消息連接來實(shí)現(xiàn),則這種耦合就是交互耦合。為使交互耦合盡可能松散,應(yīng)該遵守下述準(zhǔn)則:盡量降低消息連接的復(fù)雜程度。應(yīng)該盡量減少消息中包含的參數(shù)個(gè)數(shù),降低參數(shù)的復(fù)雜程度。減少對象發(fā)送(或接收)的消息數(shù)。(2)繼承耦合與交互耦合相反,應(yīng)該提高繼承耦合程度。繼承是一般化類與特殊類之間耦合的一種形式。從本質(zhì)上看,通過繼承關(guān)系結(jié)合起來的基類和派生類,構(gòu)成了系統(tǒng)中粒度更大的模塊。因此,它們彼此之間應(yīng)該結(jié)合得越緊密越好。為獲得緊密的繼承耦合,特殊類應(yīng)該確實(shí)是對它的一般化類的一種具體化。因此,如果一個(gè)派生類摒棄了它基類的許多屬性,則它們之間是松耦合的。在設(shè)計(jì)時(shí)應(yīng)該使特殊類盡量多繼承并使用其一般化類的屬性和服務(wù),從而更緊密地耦合到其一般化類。5.強(qiáng)內(nèi)聚內(nèi)聚衡量一個(gè)模塊內(nèi)各個(gè)元素彼此結(jié)合的緊密程度。也可以把內(nèi)聚定義為:設(shè)計(jì)中使用的一個(gè)構(gòu)件內(nèi)的各個(gè)元素,對完成一個(gè)定義明確的目的所做出的貢獻(xiàn)程度。在設(shè)計(jì)時(shí)應(yīng)該力求做到高內(nèi)聚。在面向?qū)ο笤O(shè)計(jì)中存在下述3種內(nèi)聚。(1)服務(wù)內(nèi)聚。一個(gè)服務(wù)應(yīng)該完成一個(gè)且僅完成一個(gè)功能。(2)類內(nèi)聚。設(shè)計(jì)類的原則是,一個(gè)類應(yīng)該只有一個(gè)用途,它的屬性和服務(wù)應(yīng)該是高內(nèi)聚的。類的屬性和服務(wù)應(yīng)該全都是完成該類對象的任務(wù)所必需的,其中不包含無用的屬性或服務(wù)。如果某個(gè)類有多個(gè)用途,通常應(yīng)該把它分解成多個(gè)專用的類。(3)一般-特殊內(nèi)聚。設(shè)計(jì)出的一般-特殊結(jié)構(gòu),應(yīng)該符合多數(shù)人的概念,更準(zhǔn)確地說,這種結(jié)構(gòu)應(yīng)該是對相應(yīng)的領(lǐng)域知識的正確抽取。一般說來,緊密的繼承耦合與高度的一般-特殊內(nèi)聚是一致的。6.可重用軟件重用是提高軟件開發(fā)生產(chǎn)率和目標(biāo)系統(tǒng)質(zhì)量的重要途徑。重用基本上從設(shè)計(jì)階段開始。重用有兩方面的含義:一是盡量使用已有的類(包括開發(fā)環(huán)境提供的類庫,及以往開發(fā)類似系統(tǒng)時(shí)創(chuàng)建的類),二是如果確實(shí)需要?jiǎng)?chuàng)建新類,則在設(shè)計(jì)這些新類的協(xié)議時(shí),應(yīng)該考慮將來的可重復(fù)使用性。關(guān)于軟件重用問題,將在11.3節(jié)進(jìn)一步討論。人們使用面向?qū)ο蠓椒▽W(xué)開發(fā)軟件的歷史雖然不長,但也積累了一些經(jīng)驗(yàn)??偨Y(jié)這些經(jīng)驗(yàn)得出了幾條啟發(fā)規(guī)則,它們往往能幫助軟件開發(fā)人員提高面向?qū)ο笤O(shè)計(jì)的質(zhì)量。1.設(shè)計(jì)結(jié)果應(yīng)該清晰易懂使設(shè)計(jì)結(jié)果清晰、易讀、易懂,是提高軟件可維護(hù)性和可重用性的重要措施。顯然,人們不會(huì)重用那些他們不理解的設(shè)計(jì)。保證設(shè)計(jì)結(jié)果清晰易懂的主要因素如下。11.2啟發(fā)規(guī)則(1)用詞一致。應(yīng)該使名字與它所代表的事物一致,而且應(yīng)該盡量使用人們習(xí)慣的名字。不同類中相似服務(wù)的名字應(yīng)該相同。(2)使用已有的協(xié)議。如果開發(fā)同一軟件的其他設(shè)計(jì)人員已經(jīng)建立了類的協(xié)議,或者在所使用的類庫中已有相應(yīng)的協(xié)議,則應(yīng)該使用這些已有的協(xié)議。(3)減少消息模式的數(shù)目。如果已有標(biāo)準(zhǔn)的消息協(xié)議,設(shè)計(jì)人員應(yīng)該遵守這些協(xié)議。如果確需自己建立消息協(xié)議,則應(yīng)該盡量減少消息模式的數(shù)目,只要可能,就使消息具有一致的模式,以利于讀者理解。(4)避免模糊的定義。一個(gè)類的用途應(yīng)該是有限的,而且應(yīng)該從類名可以較容易地推想出它的用途。2.一般-特殊結(jié)構(gòu)的深度應(yīng)適當(dāng)應(yīng)該使類等級中包含的層次數(shù)適當(dāng)。一般說來,在一個(gè)中等規(guī)模(大約包含100個(gè)類)的系統(tǒng)中,類等級層次數(shù)應(yīng)保持為7±2。不應(yīng)該僅僅從方便編碼的角度出發(fā)隨意創(chuàng)建派生類,應(yīng)該使一般-特殊結(jié)構(gòu)與領(lǐng)域知識或常識保持一致。3.設(shè)計(jì)簡單的類應(yīng)該盡量設(shè)計(jì)小而簡單的類,以便于開發(fā)和管理。當(dāng)類很大的時(shí)候,要記住它的所有服務(wù)是非常困難的。經(jīng)驗(yàn)表明,如果一個(gè)類的定義不超過一頁紙(或兩屏),則使用這個(gè)類是比較容易的。為使類保持簡單,應(yīng)該注意以下幾點(diǎn)。(1)避免包含過多的屬性。屬性過多通常表明這個(gè)類過分復(fù)雜了,它所完成的功能可能太多了。(2)有明確的定義。為了使類的定義明確,分配給每個(gè)類的任務(wù)應(yīng)該簡單,最好能用一兩個(gè)簡單語句描述它的任務(wù)。(3)盡量簡化對象之間的合作關(guān)系。如果需要多個(gè)對象協(xié)同配合才能做好一件事,則破壞了類的簡明性和清晰性。(4)不要提供太多服務(wù)。一個(gè)類提供的服務(wù)過多,同樣表明這個(gè)類過分復(fù)雜。典型地,一個(gè)類提供的公共服務(wù)不超過7個(gè)。在開發(fā)大型軟件系統(tǒng)時(shí),遵循上述啟發(fā)規(guī)則也會(huì)帶來另一個(gè)問題:設(shè)計(jì)出大量較小的類,這同樣會(huì)帶來一定復(fù)雜性。解決這個(gè)問題的辦法,是把系統(tǒng)中的類按邏輯分組,也就是劃分“主題”。4.使用簡單的協(xié)議一般說來,消息中的參數(shù)不要超過3個(gè)。當(dāng)然,不超過3個(gè)的限制也不是絕對的,但是,經(jīng)驗(yàn)表明,通過復(fù)雜消息相互關(guān)聯(lián)的對象是緊耦合的,對一個(gè)對象的修改往往導(dǎo)致其他對象的修改。5.使用簡單的服務(wù)面向?qū)ο笤O(shè)計(jì)出來的類中的服務(wù)通常都很小,一般只有3~5行源程序語句,可以用僅含一個(gè)動(dòng)詞和一個(gè)賓語的簡單句子描述它的功能。如果一個(gè)服務(wù)中包含了過多的源程序語句,或者語句嵌套層次太多,或者使用了復(fù)雜的CASE語句,則應(yīng)該仔細(xì)檢查這個(gè)服務(wù),設(shè)法分解或簡化它。一般說來,應(yīng)該盡量避免使用復(fù)雜的服務(wù)。如果需要在服務(wù)中使用CASE語句,通常應(yīng)該考慮用一般-特殊結(jié)構(gòu)代替這個(gè)類的可能性。6.把設(shè)計(jì)變動(dòng)減至最小通常,設(shè)計(jì)的質(zhì)量越高,設(shè)計(jì)結(jié)果保持不變的時(shí)間也越長。即使出現(xiàn)必須修改設(shè)計(jì)的情況,也應(yīng)該使修改的范圍盡可能小。理想的設(shè)計(jì)變動(dòng)曲線如圖11.1所示。在設(shè)計(jì)的早期階段,變動(dòng)較大,隨著時(shí)間推移,設(shè)計(jì)方案日趨成熟,改動(dòng)也越來越小了。圖11.1中的峰值與出現(xiàn)設(shè)計(jì)錯(cuò)誤或發(fā)生非預(yù)期變動(dòng)的情況相對應(yīng)。峰值越高,表明設(shè)計(jì)質(zhì)量越差,可重用性也越差。圖11.1理想的設(shè)計(jì)變動(dòng)情況1.重用重用也叫再用或復(fù)用,是指同一事物不作修改或稍加改動(dòng)就多次重復(fù)使用。廣義地說,軟件重用可分為以下3個(gè)層次:11.3軟件重用

11.3.1概述(1)知識重用(例如,軟件工程知識的重用)。(2)方法和標(biāo)準(zhǔn)的重用(例如,面向?qū)ο蠓椒ɑ驀抑贫ǖ能浖_發(fā)規(guī)范的重用)。(3)軟件成分的重用。前兩個(gè)重用層次屬于知識工程研究的范疇,本節(jié)僅討論軟件成分重用問題。2.軟件成分的重用級別軟件成分的重用可以進(jìn)一步劃分成以下3個(gè)級別:(1)代碼重用人們談?wù)摰米疃嗟氖谴a重用,通常把它理解為調(diào)用庫中的模塊。實(shí)際上,代碼重用也可以采用下列幾種形式中的任何一種:源代碼剪貼:這是最原始的重用形式。這種重用方式的缺點(diǎn),是復(fù)制或修改原有代碼時(shí)可能出錯(cuò),更糟糕的是,存在嚴(yán)重的配置管理問題,人們幾乎無法跟蹤原始代碼塊多次修改重用的過程。源代碼包含:許多程序設(shè)計(jì)語言都提供包含(include)庫中源代碼的機(jī)制。使用這種重用形式時(shí),配置管理問題有所緩解,因?yàn)樾薷牧藥熘性创a之后,所有包含它的程序自然都必須重新編譯。繼承:利用繼承機(jī)制重用類庫中的類時(shí),無須修改已有的代碼,就可以擴(kuò)充或具體化在庫中找出的類,因此,基本上不存在配置管理問題。(2)設(shè)計(jì)結(jié)果重用設(shè)計(jì)結(jié)果重用指的是,重用某個(gè)軟件系統(tǒng)的設(shè)計(jì)模型(即求解域模型)。這個(gè)級別的重用有助于把一個(gè)應(yīng)用系統(tǒng)移植到完全不同的軟硬件平臺上。(3)分析結(jié)果重用這是一種更高級別的重用,即重用某個(gè)系統(tǒng)的分析模型。這種重用特別適用于用戶需求未改變,但系統(tǒng)體系結(jié)構(gòu)發(fā)生了根本變化的場合。3.典型的可重用軟件成分更具體地說,可能被重用的軟件成分主要有以下10種:(1)項(xiàng)目計(jì)劃。軟件項(xiàng)目計(jì)劃的基本結(jié)構(gòu)和許多內(nèi)容(例如,軟件質(zhì)量保證計(jì)劃)都是可以跨項(xiàng)目重用的。這樣做減少了用于制定計(jì)劃的時(shí)間,也降低了與建立進(jìn)度表和進(jìn)行風(fēng)險(xiǎn)分析等活動(dòng)相關(guān)聯(lián)的不確定性。(2)成本估計(jì)。因?yàn)樵诓煌?xiàng)目中經(jīng)常含有類似的功能,所以有可能在只做極少修改或根本不做修改的情況下,重用對該功能的成本估計(jì)結(jié)果。(3)體系結(jié)構(gòu)。即使在考慮不同的應(yīng)用領(lǐng)域時(shí),也很少有截然不同的程序和數(shù)據(jù)體系結(jié)構(gòu)。因此,有可能創(chuàng)建一組類屬的體系結(jié)構(gòu)模板(例如,事務(wù)處理體系結(jié)構(gòu)),并把那些模板作為可重用的設(shè)計(jì)框架。通常把類屬的體系結(jié)構(gòu)模板稱為領(lǐng)域體系結(jié)構(gòu)。(4)需求模型和規(guī)格說明。類和對象的模型及規(guī)格說明是明顯的重用的候選者,此外,用傳統(tǒng)軟件工程方法開發(fā)的分析模型(例如,數(shù)據(jù)流圖),也是可重用的。(5)設(shè)計(jì)。用傳統(tǒng)方法開發(fā)的體系結(jié)構(gòu)、數(shù)據(jù)、接口和過程設(shè)計(jì)結(jié)果,是重用的候選者,更常見的是,系統(tǒng)和對象設(shè)計(jì)是可重用的。(6)源代碼。用兼容的程序設(shè)計(jì)語言書寫的、經(jīng)過驗(yàn)證的程序構(gòu)件,是重用的候選者。(7)用戶文檔和技術(shù)文檔。即使針對的應(yīng)用是不同的,也經(jīng)常有可能重用用戶文檔和技術(shù)文檔的大部分。(8)用戶界面。這可能是最廣泛被重用的軟件成分,GUI(圖形用戶界面)軟件經(jīng)常被重用。因?yàn)樗烧嫉揭粋€(gè)應(yīng)用程序的60%代碼量,因此,重用的效果非常顯著。(9)數(shù)據(jù)。在大多數(shù)經(jīng)常被重用的軟件成分中,被重用的數(shù)據(jù)包括:內(nèi)部表、列表和記錄結(jié)構(gòu),以及文件和完整的數(shù)據(jù)庫。(10)測試用例。一旦設(shè)計(jì)或代碼構(gòu)件將被重用,相關(guān)的測試用例應(yīng)該“附屬于”它們也被重用。利用面向?qū)ο蠹夹g(shù),可以更方便更有效地實(shí)現(xiàn)軟件重用。面向?qū)ο蠹夹g(shù)中的“類”,是比較理想的可重用軟構(gòu)件,不妨稱之為類構(gòu)件。類構(gòu)件有3種重用方式,分別是實(shí)例重用、繼承重用和多態(tài)重用。下面進(jìn)一步講述與類構(gòu)件有關(guān)的內(nèi)容。11.3.2類構(gòu)件1.可重用軟構(gòu)件應(yīng)具備的特點(diǎn)為使軟構(gòu)件也像硬件集成電路那樣,能在構(gòu)造各種各樣的軟件系統(tǒng)時(shí)方便地重復(fù)使用,就必須使它們滿足下列要求。(1)模塊獨(dú)立性強(qiáng)。具有單一、完整的功能,且經(jīng)過反復(fù)測試被確認(rèn)是正確的。它應(yīng)該是一個(gè)不受或很少受外界干擾的封裝體,其內(nèi)部實(shí)現(xiàn)在外面是不可見的。(2)具有高度可塑性。軟構(gòu)件的應(yīng)用環(huán)境比集成電路更廣闊、更復(fù)雜。顯然,要求一個(gè)軟構(gòu)件能滿足任何一個(gè)系統(tǒng)的設(shè)計(jì)需求是不現(xiàn)實(shí)的。因此,可重用的軟構(gòu)件必須具有高度可裁剪性,也就是說,必須提供為適應(yīng)特定需求而擴(kuò)充或修改已有構(gòu)件的機(jī)制,而且所提供的機(jī)制必須使用起來非常簡單方便。(3)接口清晰、簡明、可靠。軟構(gòu)件應(yīng)該提供清晰、簡明、可靠的對外接口,而且還應(yīng)該有詳盡的文檔說明,以方便用戶使用。精心設(shè)計(jì)的“類”基本上能滿足上述要求,可以認(rèn)為它是可重用軟構(gòu)件的雛形。2.類構(gòu)件的重用方式(1)實(shí)例重用由于類的封裝性,使用者無須了解實(shí)現(xiàn)細(xì)節(jié)就可以使用適當(dāng)?shù)臉?gòu)造函數(shù),按照需要?jiǎng)?chuàng)建類的實(shí)例。然后向所創(chuàng)建的實(shí)例發(fā)送適當(dāng)?shù)南ⅲ瑔?dòng)相應(yīng)的服務(wù),完成需要完成的工作。這是最基本的重用方式。此外,還可以用幾個(gè)簡單的對象作為類的成員創(chuàng)建出一個(gè)更復(fù)雜的類,這是實(shí)例重用的另一種形式。雖然實(shí)例重用是最基本的重用方式,但是,設(shè)計(jì)出一個(gè)理想的類構(gòu)件并不是一件容易的事情。例如,決定一個(gè)類對外提供多少服務(wù)就是一件相當(dāng)困難的事。提供的服務(wù)過多,會(huì)增加接口復(fù)雜度,也會(huì)使類構(gòu)件變得難于理解;提供的服務(wù)過少,則會(huì)因?yàn)檫^分一般化而失去重用價(jià)值。每個(gè)類構(gòu)件的合理服務(wù)數(shù)都與具體應(yīng)用環(huán)境密切相關(guān),因此找到一個(gè)合理的折衷值是相當(dāng)困難的。(2)繼承重用面向?qū)ο蠓椒ㄌ赜械睦^承性提供了一種對已有的類構(gòu)件進(jìn)行裁剪的機(jī)制。當(dāng)已有的類構(gòu)件不能通過實(shí)例重用完全滿足當(dāng)前系統(tǒng)需求時(shí),繼承重用提供了一種安全地修改已有類構(gòu)件,以便在當(dāng)前系統(tǒng)中重用的手段。為提高繼承重用的效果,關(guān)鍵是設(shè)計(jì)一個(gè)合理的、具有一定深度的類構(gòu)件繼承層次結(jié)構(gòu)。這樣做有下述兩個(gè)好處:每個(gè)子類在繼承父類的屬性和服務(wù)的基礎(chǔ)上,只加入少量新屬性和新服務(wù),這就不僅降低了每個(gè)類構(gòu)件的接口復(fù)雜度,表現(xiàn)出一個(gè)清晰的進(jìn)化過程,提高了每個(gè)子類的可理解性,而且為軟件開發(fā)人員提供了更多可重用的類構(gòu)件。因此,在軟件開發(fā)過程中,應(yīng)該時(shí)刻注意提取這種潛在的可重用構(gòu)件,必要時(shí)應(yīng)在領(lǐng)域?qū)<規(guī)椭?,建立符合領(lǐng)域知識的繼承層次。為多態(tài)重用奠定了良好基礎(chǔ)。(3)多態(tài)重用利用多態(tài)性不僅可以使對象的對外接口更加一般化(基類與派生類的許多對外接口是相同的),從而降低了消息連接的復(fù)雜程度,而且還提供了一種簡便可靠的軟構(gòu)件組合機(jī)制。系統(tǒng)運(yùn)行時(shí),根據(jù)接收消息的對象類型,由多態(tài)性機(jī)制啟動(dòng)正確的方法,去響應(yīng)一個(gè)一般化的消息,從而簡化了消息界面和軟構(gòu)件連接過程。為充分實(shí)現(xiàn)多態(tài)重用,在設(shè)計(jì)類構(gòu)件時(shí),應(yīng)該把注意力集中在下列一些可能影響重用性的操作上:與表示方法有關(guān)的操作。例如,不同實(shí)例的比較、顯示、擦除等等。與數(shù)據(jù)結(jié)構(gòu)、數(shù)據(jù)大小等有關(guān)的操作。與外部設(shè)備有關(guān)的操作。例如,設(shè)備控制。實(shí)現(xiàn)算法在將來可能會(huì)改進(jìn)(或改變)的核心操作。如果不預(yù)先采取適當(dāng)措施,上述這些操作會(huì)妨礙類構(gòu)件的重用。還可以把適配接口再進(jìn)一步細(xì)分為轉(zhuǎn)換接口和擴(kuò)充接口。轉(zhuǎn)換接口,是為了克服與表示方法、數(shù)據(jù)結(jié)構(gòu)或硬件特點(diǎn)相關(guān)的操作給重用帶來的困難而設(shè)計(jì)的,這類接口是每個(gè)類構(gòu)件在重用時(shí)都必須重新定義的服務(wù)的集合。當(dāng)使用C++語言編程時(shí),應(yīng)該在根類(或適當(dāng)?shù)幕?中,把屬于轉(zhuǎn)換接口的服務(wù)定義為純虛函數(shù)。如果某個(gè)服務(wù)有多種可能的實(shí)現(xiàn)算法,則應(yīng)該把它當(dāng)作擴(kuò)充接口。擴(kuò)充接口與轉(zhuǎn)換接口不同,并不需要強(qiáng)迫用戶在派生類中重新定義它們,相反,如果在派生類中沒有給出擴(kuò)充接口的新算法,則將繼承父類中的算法。當(dāng)用C++語言實(shí)現(xiàn)時(shí),在基類中把這類服務(wù)定義為普通的虛函數(shù)。1.質(zhì)量理想情況下,為了重用而開發(fā)的軟件構(gòu)件已被證明是正確的,且沒有缺陷。事實(shí)上,由于不能定期進(jìn)行形式化驗(yàn)證,錯(cuò)誤可能而且也確實(shí)存在。但是,隨著每一次重用,都會(huì)有一些錯(cuò)誤被發(fā)現(xiàn)并被清除,構(gòu)件的質(zhì)量也會(huì)隨之改善。隨著時(shí)間的推移,構(gòu)件將變成實(shí)質(zhì)上無錯(cuò)誤的。11.3.3軟件重用的效益2.生產(chǎn)率當(dāng)把可重用的軟件成分應(yīng)用于軟件開發(fā)的全過程時(shí),創(chuàng)建計(jì)劃、模型、文檔、代碼和數(shù)據(jù)所需花費(fèi)的時(shí)間將減少,從而將用較少的投入給客戶提供相同級別的產(chǎn)品,因此,生產(chǎn)率得到了提高。由于應(yīng)用領(lǐng)域、問題復(fù)雜程度、項(xiàng)目組的結(jié)構(gòu)和大小、項(xiàng)目期限、可應(yīng)用的技術(shù)等許多因素都對項(xiàng)目組的生產(chǎn)率有影響,因此,不同開發(fā)組織對軟件重用帶來生產(chǎn)率提高的數(shù)字的報(bào)告并不相同,但基本上30%~50%的重用大約可以導(dǎo)致生產(chǎn)率提高25%~40%。3.成本軟件重用帶來的凈成本節(jié)省可以用下式估算:C=Cs-Cr-Cd其中,Cs是項(xiàng)目從頭開發(fā)(沒有重用)時(shí)所需要的成本;Cr是與重用相關(guān)聯(lián)的成本;Cd是交付給客戶的軟件的實(shí)際成本。可以使用本書第13章講述的技術(shù)來估算Cs,而與重用相關(guān)聯(lián)的成本Cr主要包括下述成本:領(lǐng)域分析與建模的成本;設(shè)計(jì)領(lǐng)域體系結(jié)構(gòu)的成本;為便于重用而增加的文檔的成本;維護(hù)和完善可重用的軟件成分的成本;為從外部獲取構(gòu)件所付出的版稅和許可證費(fèi);創(chuàng)建(或購買)及運(yùn)行重用庫的費(fèi)用;對設(shè)計(jì)和實(shí)現(xiàn)可重用構(gòu)件的人員的培訓(xùn)費(fèi)用。雖然和領(lǐng)域分析及運(yùn)行重用庫相關(guān)聯(lián)的成本可能相當(dāng)高,但是它們可以由許多項(xiàng)目分?jǐn)偂I厦媪谐龅暮芏嗥渌杀舅鉀Q的問題,實(shí)際上是良好軟件工程實(shí)踐的一部分,不管是否優(yōu)先考慮重用,這些問題都應(yīng)該解決。人類解決復(fù)雜問題時(shí)普遍采用的策略是,“分而治之,各個(gè)擊破”。同樣,軟件工程師在設(shè)計(jì)比較復(fù)雜的應(yīng)用系統(tǒng)時(shí)普遍采用的策略,也是首先把系統(tǒng)分解成若干個(gè)比較小的部分,然后再分別設(shè)計(jì)每個(gè)部分。這樣做有利于降低設(shè)計(jì)的難度,有利于分工協(xié)作,也有利于維護(hù)人員對系統(tǒng)理解和維護(hù)。系統(tǒng)的主要組成部分稱為子系統(tǒng)。通常根據(jù)所提供的功能來劃分子系統(tǒng)。一般說來,子系統(tǒng)的數(shù)目應(yīng)該與系統(tǒng)規(guī)?;酒ヅ?。11.4系統(tǒng)分解各個(gè)子系統(tǒng)之間應(yīng)該具有盡可能簡單、明確的接口。接口確定了交互形式和通過子系統(tǒng)邊界的信息流,但是無須規(guī)定子系統(tǒng)內(nèi)部的實(shí)現(xiàn)算法。因此,可以相對獨(dú)立地設(shè)計(jì)各個(gè)子系統(tǒng)。在劃分和設(shè)計(jì)子系統(tǒng)時(shí),應(yīng)該盡量減少子系統(tǒng)彼此間的依賴性。采用面向?qū)ο蠓椒ㄔO(shè)計(jì)軟件系統(tǒng)時(shí),面向?qū)ο笤O(shè)計(jì)模型(即求解域的對象模型),與面向?qū)ο蠓治瞿P?即問題域的對象模型)一樣,也由主題、類與對象、結(jié)構(gòu)、屬性、服務(wù)等5個(gè)層次組成。這5個(gè)層次一層比一層表示的細(xì)節(jié)更多,可以把這5個(gè)層次想象為整個(gè)模型的水平切片。此外,大多數(shù)系統(tǒng)的面向?qū)ο笤O(shè)計(jì)模型,在邏輯上都由4大部分組成。這4大部分對應(yīng)于組成目標(biāo)系統(tǒng)的4個(gè)子系統(tǒng),它們分別是問題域子系統(tǒng)、人機(jī)交互子系統(tǒng)、任務(wù)管理子系統(tǒng)和數(shù)據(jù)管理子系統(tǒng)。當(dāng)然,在不同的軟件系統(tǒng)中,這四個(gè)子系統(tǒng)的重要程度和規(guī)??赡芟嗖詈艽螅?guī)模過大的在設(shè)計(jì)過程中應(yīng)該進(jìn)一步劃分成更小的子系統(tǒng),規(guī)模過小的可合并在其他子系統(tǒng)中。某些領(lǐng)域的應(yīng)用系統(tǒng)在邏輯上可能僅由3個(gè)(甚至少于3個(gè))子系統(tǒng)組成。可以把面向?qū)ο笤O(shè)計(jì)模型的4大組成部分想象成整個(gè)模型的4個(gè)垂直切片。典型的面向?qū)ο笤O(shè)計(jì)模型可以用圖11.2表示。圖11.2典型的面向?qū)ο笤O(shè)計(jì)模型1.子系統(tǒng)之間的兩種交互方式在軟件系統(tǒng)中,子系統(tǒng)之間的交互有兩種可能的方式,分別是客戶-供應(yīng)商(Client-supplier)關(guān)系和平等伙伴(peer-to-peer)關(guān)系。(1)客戶-供應(yīng)商關(guān)系在這種關(guān)系中,作為“客戶”的子系統(tǒng)調(diào)用作為“供應(yīng)商”的子系統(tǒng),后者完成某些服務(wù)工作并返回結(jié)果。使用這種交互方案,作為客戶的子系統(tǒng)必須了解作為供應(yīng)商的子系統(tǒng)的接口,然而后者卻無須了解前者的接口,因?yàn)槿魏谓换バ袨槎际怯汕罢唑?qū)動(dòng)的。(2)平等伙伴關(guān)系在這種關(guān)系中,每個(gè)子系統(tǒng)都可能調(diào)用其他子系統(tǒng),因此,每個(gè)子系統(tǒng)都必須了解其他子系統(tǒng)的接口。由于各個(gè)子系統(tǒng)需要相互了解對方的接口,因此這種組織系統(tǒng)的方案比起客戶-供應(yīng)商方案來,子系統(tǒng)之間的交互更復(fù)雜,而且這種交互方式還可能存在通信環(huán)路,從而使系統(tǒng)難于理解,容易發(fā)生不易察覺的設(shè)計(jì)錯(cuò)誤??偟恼f來,單向交互比雙向交互更容易理解,也更容易設(shè)計(jì)和修改,因此應(yīng)該盡量使用客戶-供應(yīng)商關(guān)系。2.組織系統(tǒng)的兩種方案把子系統(tǒng)組織成完整的系統(tǒng)時(shí),有水平層次組織和垂直塊組織兩種方案可供選擇。(1)層次組織這種組織方案把軟件系統(tǒng)組織成一個(gè)層次系統(tǒng),每層是一個(gè)子系統(tǒng)。上層在下層的基礎(chǔ)上建立,下層為實(shí)現(xiàn)上層功能而提供必要的服務(wù)。每一層內(nèi)所包含的對象,彼此間相互獨(dú)立,而處于不同層次上的對象,彼此間往往有關(guān)聯(lián)。實(shí)際上,在上、下層之間存在客戶-供應(yīng)商關(guān)系。低層子系統(tǒng)提供服務(wù),相當(dāng)于供應(yīng)商,上層子系統(tǒng)使用下層提供的服務(wù),相當(dāng)于客戶。層次結(jié)構(gòu)又可進(jìn)一步劃分成兩種模式:封閉式和開放式。所謂封閉式,就是每層子系統(tǒng)僅僅使用其直接下層提供的服務(wù)。由于一個(gè)層次的接口只影響與其緊相鄰的上一層,因此,這種工作模式降低了各層次之間的相互依賴性,更容易理解和修改。在開放模式中,某層子系統(tǒng)可以使用處于其下面的任何一層子系統(tǒng)所提供的服務(wù)。這種工作模式的優(yōu)點(diǎn),是減少了需要在每層重新定義的服務(wù)數(shù)目,使得整個(gè)系統(tǒng)更高效更緊湊。但是,開放模式的系統(tǒng)不符合信息隱藏原則,對任何一個(gè)子系統(tǒng)的修改都會(huì)影響處在更高層次的那些子系統(tǒng)。設(shè)計(jì)軟件系統(tǒng)時(shí)到底采用哪種結(jié)構(gòu)模式,需要權(quán)衡效率和模塊獨(dú)立性等多種因素,通盤考慮以后再做決定。通常,在需求陳述中只描述了對系統(tǒng)頂層和底層的需求,頂層就是用戶看到的目標(biāo)系統(tǒng),底層則是可以使用的資源。這兩層往往差異很大,設(shè)計(jì)者必須設(shè)計(jì)一些中間層次,以減少不同層次之間的概念差異。(2)塊狀組織這種組織方案把軟件系統(tǒng)垂直地分解成若干個(gè)相對獨(dú)立的、弱耦合的子系統(tǒng),一個(gè)子系統(tǒng)相當(dāng)于一塊,每塊提供一種類型的服務(wù)。利用層次和塊的各種可能的組合,可以成功地由多個(gè)子系統(tǒng)組成一個(gè)完整的軟件系統(tǒng)。當(dāng)混合使用層次結(jié)構(gòu)和塊狀結(jié)構(gòu)時(shí),同一層次可以由若干塊組成,而同一塊也可以分為若干層。例如,圖11.3表示一個(gè)應(yīng)用系統(tǒng)的組織結(jié)構(gòu),這個(gè)應(yīng)用系統(tǒng)采用了層次與塊狀的混合結(jié)構(gòu)。3.設(shè)計(jì)系統(tǒng)的拓?fù)浣Y(jié)構(gòu)由子系統(tǒng)組成完整的系統(tǒng)時(shí),典型的拓?fù)浣Y(jié)構(gòu)有管道形、樹形、星形等。設(shè)計(jì)者應(yīng)該采用與問題結(jié)構(gòu)相適應(yīng)的、盡可能簡單的拓?fù)浣Y(jié)構(gòu),以減少子系統(tǒng)之間的交互數(shù)量。圖11.3典型應(yīng)用系統(tǒng)的組織結(jié)構(gòu)使用面向?qū)ο蠓椒ㄩ_發(fā)軟件時(shí),在分析與設(shè)計(jì)之間并沒有明確的分界線,對于問題域子系統(tǒng)來說,情況更是如此。但是,分析與設(shè)計(jì)畢竟是性質(zhì)不同的兩類開發(fā)工作,分析工作可以而且應(yīng)該與具體實(shí)現(xiàn)無關(guān),設(shè)計(jì)工作則在很大程度上受具體實(shí)現(xiàn)環(huán)境的約束。在開始進(jìn)行設(shè)計(jì)工作之前(至少在完成設(shè)計(jì)之前),設(shè)計(jì)者應(yīng)該了解本項(xiàng)目預(yù)計(jì)要使用的編程語言,可用的軟構(gòu)件庫(主要是類庫)以及程序員的編程經(jīng)驗(yàn)。11.5設(shè)計(jì)問題域子系統(tǒng)通過面向?qū)ο蠓治鏊贸龅膯栴}域精確模型,為設(shè)計(jì)問題域子系統(tǒng)奠定了良好的基礎(chǔ),建立了完整的框架。只要可能,就應(yīng)該保持面向?qū)ο蠓治鏊⒌膯栴}域結(jié)構(gòu)。通常,面向?qū)ο笤O(shè)計(jì)僅需從實(shí)現(xiàn)角度對問題域模型做一些補(bǔ)充或修改,主要是增添、合并或分解類與對象、屬性及服務(wù),調(diào)整繼承關(guān)系等等。當(dāng)問題域子系統(tǒng)過分復(fù)雜龐大時(shí),應(yīng)該把它進(jìn)一步分解成若干個(gè)更小的子系統(tǒng)。使用面向?qū)ο蠓椒▽W(xué)開發(fā)軟件,能夠保持問題域組織框架的穩(wěn)定性,從而便于追蹤分析、設(shè)計(jì)和編程的結(jié)果。在設(shè)計(jì)與實(shí)現(xiàn)過程中所做的細(xì)節(jié)修改(例如,增加具體類,增加屬性或服務(wù)),并不影響開發(fā)結(jié)果的穩(wěn)定性,因?yàn)橄到y(tǒng)的總體框架是基于問題域的。對于需求可能隨時(shí)間變化的系統(tǒng)來說,穩(wěn)定性是至關(guān)重要的。穩(wěn)定性也是能夠在類似系統(tǒng)中重用分析、設(shè)計(jì)和編程結(jié)果的關(guān)鍵因素。為更好地支持系統(tǒng)在其生命期中的擴(kuò)充,也同樣需要穩(wěn)定性。下面介紹,在面向?qū)ο笤O(shè)計(jì)過程中,可能對面向?qū)ο蠓治鏊贸龅膯栴}域模型做的補(bǔ)充或修改。1.調(diào)整需求有兩種情況會(huì)導(dǎo)致修改通過面向?qū)ο蠓治鏊_定的系統(tǒng)需求:一是用戶需求或外部環(huán)境發(fā)生了變化;二是分析員對問題域理解不透徹或缺乏領(lǐng)域?qū)<規(guī)椭灾旅嫦驅(qū)ο蠓治瞿P筒荒芡暾?、?zhǔn)確地反映用戶的真實(shí)需求。無論出現(xiàn)上述哪種情況,通常都只需簡單地修改面向?qū)ο蠓治鼋Y(jié)果,然后再把這些修改反映到問題域子系統(tǒng)中。2.重用已有的類代碼重用從設(shè)計(jì)階段開始,在研究面向?qū)ο蠓治鼋Y(jié)果時(shí)就應(yīng)該尋找使用已有類的方法。若因?yàn)闆]有合適的類可以重用而確實(shí)需要?jiǎng)?chuàng)建新的類,則在設(shè)計(jì)這些新類的協(xié)議時(shí),必須考慮到將來的可重用性。如果有可能重用已有的類,則重用已有類的典型過程如下:(1)選擇有可能被重用的已有類,標(biāo)出這些候選類中對本問題無用的屬性和服務(wù),盡量重用那些能使無用的屬性和服務(wù)降到最低程度的類。(2)在被重用的已有類和問題域類之間添加泛化關(guān)系(即從被重用的已有類派生出問題域類)。(3)標(biāo)出問題域類中從已有類繼承來的屬性和服務(wù),現(xiàn)在已經(jīng)無須在問題域類內(nèi)定義它們了。(4)修改與問題域類相關(guān)的關(guān)聯(lián),必要時(shí)改為與被重用的已有類相關(guān)的關(guān)聯(lián)。3.把問題域類組合在一起在面向?qū)ο笤O(shè)計(jì)過程中,設(shè)計(jì)者往往通過引入一個(gè)根類而把問題域類組合在一起。事實(shí)上,這是在沒有更先進(jìn)的組合機(jī)制可用時(shí)才采用的一種組合方法。此外,這樣的根類還可以用來建立協(xié)議。4.增添一般化類以建立協(xié)議在設(shè)計(jì)過程中常常發(fā)現(xiàn),一些具體類需要有一個(gè)公共的協(xié)議,也就是說,它們都需要定義一組類似的服務(wù)。在這種情況下可以引入一個(gè)附加類(例如,根類),以便建立這個(gè)協(xié)議(即命名公共服務(wù)集合,這些服務(wù)在具體類中仔細(xì)定義)。5.調(diào)整繼承層次如果面向?qū)ο蠓治瞿P椭邪硕嘀乩^承關(guān)系,然而所使用的程序設(shè)計(jì)語言卻并不提供多重繼承機(jī)制,則必須修改面向?qū)ο蠓治龅慕Y(jié)果。即使使用支持多重繼承的語言,有時(shí)也會(huì)出于實(shí)現(xiàn)考慮而對面向?qū)ο蠓治鼋Y(jié)果作一些調(diào)整。下面分幾種情況討論:(1)使用多重繼承機(jī)制使用多重繼承機(jī)制時(shí),應(yīng)該避免出現(xiàn)屬性及服務(wù)的命名沖突。下面通過例子說明避免命名沖突的方法。圖11.4是一種多重繼承模式的例子,這種模式可以稱為窄菱形模式。使用這種模式時(shí)出現(xiàn)屬性及服務(wù)命名沖突的可能性比較大。圖11.5(見書262頁)是另一種多重繼承模式,稱為闊菱形模式。使用這種模式時(shí),屬性及服務(wù)的名字發(fā)生沖突的可能性比較小,但是,它需要用更多的類才能表示同一個(gè)設(shè)計(jì)。圖11.4窄菱形模式(2)使用單繼承機(jī)制如果打算使用僅提供單繼承機(jī)制的語言實(shí)現(xiàn)系統(tǒng),則必須把面向?qū)ο蠓治瞿P椭械亩嘀乩^承結(jié)構(gòu)轉(zhuǎn)換成單繼承結(jié)構(gòu)。常見的做法是,把多重繼承結(jié)構(gòu)簡化成單一的單繼承層次結(jié)構(gòu),如圖11.6所示。顯然,在多重繼承結(jié)構(gòu)中的某些繼承關(guān)系,經(jīng)簡化后將不再存在,這表明需要在各個(gè)具體類中重復(fù)定義某些屬性和服務(wù)。圖11.6把多重繼承簡化為單一層次的單繼承6.ATM系統(tǒng)實(shí)例圖11.7描繪了上章給出的ATM系統(tǒng)的問題域子系統(tǒng)的結(jié)構(gòu)。由于在面向?qū)ο蠓治鲞^程中已經(jīng)對ATM系統(tǒng)做了相當(dāng)仔細(xì)的分析,而且假設(shè)所使用的實(shí)現(xiàn)環(huán)境能完全支持面向?qū)ο蠓治瞿P偷膶?shí)現(xiàn),因此,在面向?qū)ο笤O(shè)計(jì)階段無須對已有的問題域模型作實(shí)質(zhì)性的修改或擴(kuò)充。圖11.7ATM系統(tǒng)問題域子系統(tǒng)的結(jié)構(gòu)在面向?qū)ο蠓治鲞^程中,已經(jīng)對用戶界面需求做了初步分析,在面向?qū)ο笤O(shè)計(jì)過程中,則應(yīng)該對系統(tǒng)的人機(jī)交互子系統(tǒng)進(jìn)行詳細(xì)設(shè)計(jì),以確定人機(jī)交互的細(xì)節(jié),其中包括指定窗口和報(bào)表的形式、設(shè)計(jì)命令層次等項(xiàng)內(nèi)容。11.6設(shè)計(jì)人機(jī)交互子系統(tǒng)人機(jī)交互部分的設(shè)計(jì)結(jié)果,將對用戶情緒和工作效率產(chǎn)生重要影響。人機(jī)界面設(shè)計(jì)得好,則會(huì)使系統(tǒng)對用戶產(chǎn)生吸引力,用戶在使用系統(tǒng)的過程中會(huì)感到興奮,能夠激發(fā)用戶的創(chuàng)造力,提高工作效率;相反,人機(jī)界面設(shè)計(jì)得不好,用戶在使用過程中就會(huì)感到不方便、不習(xí)慣,甚至?xí)a(chǎn)生厭煩和惱怒的情緒。由于對人機(jī)界面的評價(jià),在很大程度上由人的主觀因素決定,因此,使用由原型支持的系統(tǒng)化的設(shè)計(jì)策略,是成功地設(shè)計(jì)人機(jī)交互子系統(tǒng)的關(guān)鍵。本節(jié)僅從面向?qū)ο笤O(shè)計(jì)的角度補(bǔ)充講述一下設(shè)計(jì)人機(jī)交互子系統(tǒng)的策略。1.分類用戶人機(jī)交互界面是給用戶使用的,顯然,為設(shè)計(jì)好人機(jī)交互子系統(tǒng),設(shè)計(jì)者應(yīng)該認(rèn)真研究使用它的用戶。應(yīng)該深入到用戶的工作現(xiàn)場,仔細(xì)觀察用戶是怎樣做他們的工作的,這對設(shè)計(jì)好人機(jī)交互界面是非常必要的。為了更好地了解用戶的需要與愛好,以便設(shè)計(jì)出符合用戶需要的界面,設(shè)計(jì)者首先應(yīng)該把將來可能與系統(tǒng)交互的用戶分類。通常從下列幾個(gè)不同角度進(jìn)行分類:按技能水平分類(新手、初級、中級、高級)。按職務(wù)分類(總經(jīng)理、經(jīng)理、職員)。按所屬集團(tuán)分類(職員、顧客)。2.描述用戶應(yīng)該仔細(xì)了解將來使用系統(tǒng)的每類用戶的情況,把獲得的下列各項(xiàng)信息記錄下來:用戶類型。使用系統(tǒng)欲達(dá)到的目的。特征(年齡、性別、受教育程度、限制因素等)。關(guān)鍵的成功因素(需求、愛好、習(xí)慣等)。技能水平。完成本職工作的腳本。3.設(shè)計(jì)命令層次設(shè)計(jì)命令層次的工作通常包含以下幾項(xiàng)內(nèi)容。(1)研究現(xiàn)有的人機(jī)交互含義和準(zhǔn)則現(xiàn)在,Windows已經(jīng)成了微機(jī)上圖形用戶界面事實(shí)上的工業(yè)標(biāo)準(zhǔn)。所有Windows應(yīng)用程序的基本外觀及給用戶的感受都是相同的。Windows程序通常還遵守廣大用戶習(xí)以為常的許多約定。設(shè)計(jì)圖形用戶界面時(shí),應(yīng)該保持與普通Windows應(yīng)用程序界面相一致,并遵守廣大用戶習(xí)慣的約定,這樣才會(huì)被用戶接受和喜愛。(2)確定初始的命令層次所謂命令層次,實(shí)質(zhì)上是用過程抽象機(jī)制組織起來的、可供選用的服務(wù)的表示形式。設(shè)計(jì)命令層次時(shí),通常先從對服務(wù)的過程抽象著手,然后再進(jìn)一步修改它們,以適合具體應(yīng)用環(huán)境的需要。(3)精化命令層次為進(jìn)一步修改完善初始的命令層次,應(yīng)該考慮下列一些因素:次序:仔細(xì)選擇每個(gè)服務(wù)的名字,并在命令層的每一部分內(nèi)把服務(wù)排好次序。排序時(shí)或者把最常用的服務(wù)放在最前面,或者按照用戶習(xí)慣的工作步驟排序。整體-部分關(guān)系:尋找在這些服務(wù)中存在的整體-部分模式,這樣做有助于在命令層中分組組織服務(wù)。寬度和深度:由于人的短期記憶能力有限,命令層次的寬度和深度都不應(yīng)該過大。操作步驟:應(yīng)該用盡量少的單擊、拖動(dòng)和擊鍵組合來表達(dá)命令,而且應(yīng)該為高級用戶提供簡捷的操作方法。4.設(shè)計(jì)人機(jī)交互類人機(jī)交互類與所使用的操作系統(tǒng)及編程語言密切相關(guān)。例如,在Windows環(huán)境下運(yùn)行的VisualC++語言提供了MFC類庫,設(shè)計(jì)人機(jī)交互類時(shí),往往僅需從MFC類庫中選出一些適用的類,然后從這些類派生出符合自己需要的類就可以了。雖然從概念上說,不同對象可以并發(fā)地工作,但是,在實(shí)際系統(tǒng)中,許多對象之間往往存在相互依賴關(guān)系。此外,在實(shí)際使用的硬件中,可能僅由一個(gè)處理器支持多個(gè)對象。因此,設(shè)計(jì)工作的一項(xiàng)重要內(nèi)容就是,確定哪些是必須同時(shí)動(dòng)作的對象,哪些是相互排斥的對象。然后進(jìn)一步設(shè)計(jì)任務(wù)管理子系統(tǒng)。11.7設(shè)計(jì)任務(wù)管理子系統(tǒng)1.分析并發(fā)性通過面向?qū)ο蠓治鼋⑵饋淼膭?dòng)態(tài)模型,是分析并發(fā)性的主要依據(jù)。如果兩個(gè)對象彼此間不存在交互,或者它們同時(shí)接受事件,則這兩個(gè)對象在本質(zhì)上是并發(fā)的。通過檢查各個(gè)對象的狀態(tài)圖及它們之間交換的事件,能夠把若干個(gè)非并發(fā)的對象歸并到一條控制線中。所謂控制線,是一條遍及狀態(tài)圖集合的路徑,在這條路徑上每次只有一個(gè)對象是活動(dòng)的。在計(jì)算機(jī)系統(tǒng)中用任務(wù)(task)實(shí)現(xiàn)控制線,一般認(rèn)為任務(wù)是進(jìn)程(process)的別名。通常把多個(gè)任務(wù)的并發(fā)執(zhí)行稱為多任務(wù)。對于某些應(yīng)用系統(tǒng)來說,通過劃分任務(wù),可以簡化系統(tǒng)的設(shè)計(jì)及編碼工作。不同的任務(wù)標(biāo)識了必須同時(shí)發(fā)生的不同行為。這種并發(fā)行為既可以在不同的處理器上實(shí)現(xiàn),也可以在單個(gè)處理器上利用多任務(wù)操作系統(tǒng)仿真實(shí)現(xiàn)(通常采用時(shí)間分片策略仿真多處理器環(huán)境)。2.設(shè)計(jì)任務(wù)管理子系統(tǒng)常見的任務(wù)有事件驅(qū)動(dòng)型任務(wù)、時(shí)鐘驅(qū)動(dòng)型任務(wù)、優(yōu)先任務(wù)、關(guān)鍵任務(wù)和協(xié)調(diào)任務(wù)等。設(shè)計(jì)任務(wù)管理子系統(tǒng),包括確定各類任務(wù)并把任務(wù)分配給適當(dāng)?shù)挠布蜍浖?zhí)行。(1)確定事件驅(qū)動(dòng)型任務(wù)某些任務(wù)是由事件驅(qū)動(dòng)的,這類任務(wù)可能主要完成通信工作。例如,與設(shè)備、屏幕窗口、其他任務(wù)、子系統(tǒng)、另一個(gè)處理器或其他系統(tǒng)通信。事件通常是表明某些數(shù)據(jù)到達(dá)的信號。在系統(tǒng)運(yùn)行時(shí),這類任務(wù)的工作過程如下:任務(wù)處于睡眠狀態(tài)(不消耗處理器時(shí)間),等待來自數(shù)據(jù)線或其他數(shù)據(jù)源的中斷;一旦接收到中斷就喚醒了該任務(wù),接收數(shù)據(jù)并把數(shù)據(jù)放入內(nèi)存緩沖區(qū)或其他目的地,通知需要知道這件事的對象,然后該任務(wù)又回到睡眠狀態(tài)。(2)確定時(shí)鐘驅(qū)動(dòng)型任務(wù)某些任務(wù)每隔一定時(shí)間間隔就被觸發(fā)以執(zhí)行某些處理,例如,某些設(shè)備需要周期性地獲得數(shù)據(jù);某些人機(jī)接口、子系統(tǒng)、任務(wù)、處理器或其他系統(tǒng)也可能需要周期性地通信。在這些場合往往需要使用時(shí)鐘驅(qū)動(dòng)型任務(wù)。時(shí)鐘驅(qū)動(dòng)型任務(wù)的工作過程如下:任務(wù)設(shè)置了喚醒時(shí)間后進(jìn)入睡眠狀態(tài);任務(wù)睡眠(不消耗處理器時(shí)間),等待來自系統(tǒng)的中斷;一旦接收到這種中斷,任務(wù)就被喚醒并做它的工作,通知有關(guān)的對象,然后該任務(wù)又回到睡眠狀態(tài)。(3)確定優(yōu)先任務(wù)優(yōu)先任務(wù)可以滿足高優(yōu)先級或低優(yōu)先級的處理需求:高優(yōu)先級:某些服務(wù)具有很高的優(yōu)先級,為了在嚴(yán)格限定的時(shí)間內(nèi)完成這種服務(wù),可能需要把這類服務(wù)分離成獨(dú)立的任務(wù)。低優(yōu)先級:與高優(yōu)先級相反,有些服務(wù)是低優(yōu)先級的,屬于低優(yōu)先級處理(通常指那些背景處理)。設(shè)計(jì)時(shí)可能用額外的任務(wù)把這樣的處理分離出來。(4)確定關(guān)鍵任務(wù)關(guān)鍵任務(wù)是有關(guān)系統(tǒng)成功或失敗的關(guān)鍵處理,這類處理通常都有嚴(yán)格的可靠性要求。在設(shè)計(jì)過程中可能用額外的任務(wù)把這樣的關(guān)鍵處理分離出來,以滿足高可靠性處理的要求。對高可靠性處理應(yīng)該精心設(shè)計(jì)和編碼,并且應(yīng)該嚴(yán)格測試。(5)確定協(xié)調(diào)任務(wù)當(dāng)系統(tǒng)中存在3個(gè)以上任務(wù)時(shí),就應(yīng)該增加一個(gè)任務(wù),用它作為協(xié)調(diào)任務(wù)。引入?yún)f(xié)調(diào)任務(wù)會(huì)增加系統(tǒng)的總開銷(增加從一個(gè)任務(wù)到另一個(gè)任務(wù)的轉(zhuǎn)換時(shí)間),但是引入?yún)f(xié)調(diào)任務(wù)有助于把不同任務(wù)之間的協(xié)調(diào)控制封裝起來。使用狀態(tài)轉(zhuǎn)換矩陣可以比較方便地描述該任務(wù)的行為。這類任務(wù)應(yīng)該僅做協(xié)調(diào)工作,不要讓它再承擔(dān)其他服務(wù)工作。(6)盡量減少任務(wù)數(shù)必須仔細(xì)分析和選擇每個(gè)確實(shí)需要的任務(wù)。應(yīng)該使系統(tǒng)中包含的任務(wù)數(shù)盡量少。設(shè)計(jì)多任務(wù)系統(tǒng)的主要問題是,設(shè)計(jì)者常常為了自己處理時(shí)的方便而輕率地定義過多的任務(wù)。這樣做加大了設(shè)計(jì)工作的技術(shù)復(fù)雜度,并使系統(tǒng)變得不易理解,從而也加大了系統(tǒng)維護(hù)的難度。(7)確定資源需求使用多處理器或固件,主要是為了滿足高性能的需求。設(shè)計(jì)者必須通過計(jì)算系統(tǒng)載荷(即每秒處理的業(yè)務(wù)數(shù)及處理一個(gè)業(yè)務(wù)所花費(fèi)的時(shí)間),來估算所需要的CPU(或其他固件)的處理能力。設(shè)計(jì)者應(yīng)該綜合考慮各種因素,以決定哪些子系統(tǒng)用硬件實(shí)現(xiàn),哪些子系統(tǒng)用軟件實(shí)現(xiàn)。下述兩個(gè)因素可能是使用硬件實(shí)現(xiàn)某些子系統(tǒng)的主要原因:現(xiàn)有的硬件完全能滿足某些方面的需求,例如,買一塊浮點(diǎn)運(yùn)算卡比用軟件實(shí)現(xiàn)浮點(diǎn)運(yùn)算要容易得多。專用硬件比通用的CPU性能更高。例如,目前在信號處理系統(tǒng)中廣泛使用固件實(shí)現(xiàn)快速傅里葉變換。設(shè)計(jì)者在決定到底采用軟件還是硬件的時(shí)候,必須綜合權(quán)衡一致性、成本、性能等多種因素,還要考慮未來的可擴(kuò)充性和可修改性。數(shù)據(jù)管理子系統(tǒng)是系統(tǒng)存儲(chǔ)或檢索對象的基本設(shè)施,它建立在某種數(shù)據(jù)存儲(chǔ)管理系統(tǒng)之上,并且隔離了數(shù)據(jù)存儲(chǔ)管理模式(文件、關(guān)系數(shù)據(jù)庫或面向?qū)ο髷?shù)據(jù)庫)的影響。11.8設(shè)計(jì)數(shù)據(jù)管理子系統(tǒng)不同的數(shù)據(jù)存儲(chǔ)管理模式有不同的特點(diǎn),適用范圍也不相同,設(shè)計(jì)者應(yīng)該根據(jù)應(yīng)用系統(tǒng)的特點(diǎn)選擇適用的模式。1.文件管理系統(tǒng)文件管理系統(tǒng)是操作系統(tǒng)的一個(gè)組成部分,使用它長期保存數(shù)據(jù)具有成本低和簡單等特點(diǎn),但是,文件操作的級別低,為提供適當(dāng)?shù)某橄蠹墑e還必須編寫額外的代碼。此外,不同操作系統(tǒng)的文件管理系統(tǒng)往往有明顯差異。11.8.1選擇數(shù)據(jù)存儲(chǔ)管理模式2.關(guān)系數(shù)據(jù)庫管理系統(tǒng)關(guān)系數(shù)據(jù)庫管理系統(tǒng)的理論基礎(chǔ)是關(guān)系代數(shù),它不僅理論基礎(chǔ)堅(jiān)實(shí)而且有下列一些主要優(yōu)點(diǎn):(1)提供了各種最基本的數(shù)據(jù)管理功能(例如,中斷恢復(fù),多用戶共享,多應(yīng)用共享,完整性,事務(wù)支持等)。(2)為多種應(yīng)用提供了一致的接口。(3)標(biāo)準(zhǔn)化的語言(大多數(shù)商品化關(guān)系數(shù)據(jù)庫管理系統(tǒng)都使用SQL語言)。但是,為了做到通用與一致,關(guān)系數(shù)據(jù)庫管理系統(tǒng)通常都相當(dāng)復(fù)雜,且有下述一些具體缺點(diǎn),以致限制了這種系統(tǒng)的普遍使用:(1)運(yùn)行開銷大:即使只完成簡單的事務(wù)(例如,只修改表中的一行),也需要較長的時(shí)間。(2)不能滿足高級應(yīng)用的需求:關(guān)系數(shù)據(jù)庫管理系統(tǒng)是為商務(wù)應(yīng)用服務(wù)的,商務(wù)應(yīng)用中數(shù)據(jù)量雖大但數(shù)據(jù)結(jié)構(gòu)卻比較簡單。事實(shí)上,關(guān)系數(shù)據(jù)庫管理系統(tǒng)很難用在數(shù)據(jù)類型豐富或操作不標(biāo)準(zhǔn)的應(yīng)用中。(3)與程序設(shè)計(jì)語言的連接不自然:SQL語言支持面向集合的操作,是一種非過程性語言;然而大多數(shù)程序設(shè)計(jì)語言本質(zhì)上卻是過程性的,每次只能處理一個(gè)記錄。3.面向?qū)ο髷?shù)據(jù)庫管理系統(tǒng)面向?qū)ο髷?shù)據(jù)庫管理系統(tǒng)是一種新技術(shù),主要有兩種設(shè)計(jì)途徑:擴(kuò)展的關(guān)系數(shù)據(jù)庫管理系統(tǒng)和擴(kuò)展的面向?qū)ο蟪绦蛟O(shè)計(jì)語言。(1)擴(kuò)展的關(guān)系數(shù)據(jù)庫管理系統(tǒng)是在關(guān)系數(shù)據(jù)庫的基礎(chǔ)上,增加了抽象數(shù)據(jù)類型和繼承機(jī)制,此外還增加了創(chuàng)建及管理類和對象的通用服務(wù)。(2)擴(kuò)展的面向?qū)ο蟪绦蛟O(shè)計(jì)語言擴(kuò)充了面向?qū)ο蟪绦蛟O(shè)計(jì)語言的語法和功能,增加了在數(shù)據(jù)庫中存儲(chǔ)和管理對象的機(jī)制。開發(fā)人員可以用統(tǒng)一的面向?qū)ο笥^點(diǎn)進(jìn)行設(shè)計(jì),不再需要區(qū)分存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)和程序數(shù)據(jù)結(jié)構(gòu)(即生命期短暫的數(shù)據(jù))。目前,大多數(shù)“對象”數(shù)據(jù)管理模式都采用“復(fù)制對象”的方法:先保留對象值,然后,在需要時(shí)創(chuàng)建該對象的一個(gè)副本。擴(kuò)展的面向?qū)ο蟪绦蛟O(shè)計(jì)語言則擴(kuò)充了這種機(jī)制,它支持“永久對象”方法:準(zhǔn)確存儲(chǔ)對象(包括對象的內(nèi)部標(biāo)識在內(nèi)),而不是僅僅存儲(chǔ)對象值。使用這種方法,當(dāng)從存儲(chǔ)器中檢索出一個(gè)對象的時(shí)候,它就完全等同于原先存在的那個(gè)對象?!坝谰脤ο蟆狈椒?,為在多用戶環(huán)境中從對象服務(wù)器中共享對象奠定了基礎(chǔ)。設(shè)計(jì)數(shù)據(jù)管理子系統(tǒng),既需要設(shè)計(jì)數(shù)據(jù)格式又需要設(shè)計(jì)相應(yīng)的服務(wù)。1.設(shè)計(jì)數(shù)據(jù)格式設(shè)計(jì)數(shù)據(jù)格式的方法與所使用的數(shù)據(jù)存儲(chǔ)管理模式密切相關(guān),下面分別介紹適用于每種數(shù)據(jù)存儲(chǔ)管理模式的設(shè)計(jì)方法:(1)文件系統(tǒng)定義第一范式表:列出每個(gè)類的屬性表;把屬性表規(guī)范成第一范式,從而得到第一范式表的定義。11.8.2設(shè)計(jì)數(shù)據(jù)管理子系統(tǒng)為每個(gè)第一范式表定義一個(gè)文件。測量性能和需要的存儲(chǔ)容量。修改原設(shè)計(jì)的第一范式,以滿足性能和存儲(chǔ)需求。必要時(shí)把泛化結(jié)構(gòu)的屬性壓縮在單個(gè)文件中,以減少文件數(shù)量。必要時(shí)把某些屬性組合在一起,并用某種編碼值表示這些屬性,而不再分別使用獨(dú)立的域表示每個(gè)屬性。這樣做可以減少所需要的存儲(chǔ)空間,但是增加了處理時(shí)間。(2)關(guān)系數(shù)據(jù)庫管理系統(tǒng)定義第三范式表:列出每個(gè)類的屬性表;把屬性表規(guī)范成第三范式,從而得出第三范式表的定義。為每個(gè)第三范式表定義一個(gè)數(shù)據(jù)庫表。測量性能和需要的存儲(chǔ)容量。修改先前設(shè)計(jì)的第三范式,以滿足性能和存儲(chǔ)需求。(3)面向?qū)ο髷?shù)據(jù)庫管理系統(tǒng)擴(kuò)展的關(guān)系數(shù)據(jù)庫途徑:使用與關(guān)系數(shù)據(jù)庫管理系統(tǒng)相同的方法。擴(kuò)展的面向?qū)ο蟪绦蛟O(shè)計(jì)語言途徑:不需要規(guī)范化屬性的步驟,因?yàn)閿?shù)據(jù)庫管理系統(tǒng)本身具有把對象值映射成存儲(chǔ)值的功能。2.設(shè)計(jì)相應(yīng)的服務(wù)如果某個(gè)類的對象需要存儲(chǔ)起來,則在這個(gè)類中增加一個(gè)屬性和服務(wù),用于完成存儲(chǔ)對象自身的工作。應(yīng)該把為此目的增加的屬性和服務(wù)作為“隱含”的屬性和服務(wù),即無須在面向?qū)ο笤O(shè)計(jì)模型的屬性和服務(wù)層中顯式地表示它們,僅需在關(guān)于類與對象的文檔中描述它們。這樣設(shè)計(jì)之后,對象將知道怎樣存儲(chǔ)自己。用于“存儲(chǔ)自己”的屬性和服務(wù),在問題域子系統(tǒng)和數(shù)據(jù)管理子系統(tǒng)之間構(gòu)成一座必要的橋梁。利用多重繼承機(jī)制,可以在某個(gè)適當(dāng)?shù)幕愔卸x這樣的屬性和服務(wù),然后,如果某個(gè)類的對象需要長期存儲(chǔ),該類就從基類中繼承這樣的屬性和服務(wù)。下面介紹使用不同數(shù)據(jù)存儲(chǔ)管理模式時(shí)的設(shè)計(jì)要點(diǎn)。(1)文件系統(tǒng)被存儲(chǔ)的對象需要知道打開哪個(gè)(些)文件,怎樣把文件定位到正確的記錄上,怎樣檢索出舊值(如果有的話),以及怎樣用現(xiàn)有值更新它們。此外,還應(yīng)該定義一個(gè)ObjectServer(對象服務(wù)器)類,并創(chuàng)建它的實(shí)例。該類提供下列服務(wù):通知對象保存自身;檢索已存儲(chǔ)的對象(查找,讀值,創(chuàng)建并初始化對象),以便把這些對象提供給其他子系統(tǒng)使用。注意,為提高性能應(yīng)該批量處理訪問文件的要求。(2)關(guān)系數(shù)據(jù)庫管理系統(tǒng)被存儲(chǔ)的對象,應(yīng)該知道訪問哪些數(shù)據(jù)庫表,怎樣訪問所需要的行,怎樣檢索出舊值(如果有的話),以及怎樣用現(xiàn)有值更新它們。此外,還應(yīng)該定義一個(gè)ObjectServer類,并聲明它的對象。該類提供下列服務(wù):通知對象保存自身;檢索已存儲(chǔ)的對象(查找,讀值,創(chuàng)建并初始化對象),以便由其他子系統(tǒng)使用這些對象。(3)面向?qū)ο髷?shù)據(jù)庫管理系統(tǒng)擴(kuò)展的關(guān)系數(shù)據(jù)庫途徑:與使用關(guān)系數(shù)據(jù)庫管理系統(tǒng)時(shí)方法相同。擴(kuò)展的面向?qū)ο蟪绦蛟O(shè)計(jì)語言途徑:無須增加服務(wù),這種數(shù)據(jù)庫管理系統(tǒng)已經(jīng)給每個(gè)對象提供了“存儲(chǔ)自己”的行為。只需給需要長期保存的對象加個(gè)標(biāo)記,然后由面向?qū)ο髷?shù)據(jù)庫管理系統(tǒng)負(fù)責(zé)存儲(chǔ)和恢復(fù)這類對象。為具體說明數(shù)據(jù)管理子系統(tǒng)的設(shè)計(jì)方法,讓我們再看看圖11.7所示的ATM系統(tǒng)。從圖中可以看出,惟一的永久性數(shù)據(jù)存儲(chǔ)放在分行計(jì)算機(jī)中。因?yàn)楸仨毐3謹(jǐn)?shù)據(jù)的一致性和完整性,而且常常有多個(gè)并發(fā)事務(wù)同時(shí)訪問這些數(shù)據(jù),因此,采用成熟的商品化關(guān)系數(shù)據(jù)庫管理系統(tǒng)存儲(chǔ)數(shù)據(jù)。應(yīng)該把每個(gè)事務(wù)作為一個(gè)不可分割的批操作來處理,由事務(wù)封鎖賬戶直到該事務(wù)結(jié)束為止。11.8.3例子在這個(gè)例子中,需要存儲(chǔ)的對象主要是賬戶類的對象。為了支持?jǐn)?shù)據(jù)管理子系統(tǒng)的實(shí)現(xiàn),賬戶類對象必須知道自己是怎樣存儲(chǔ)的,有兩種方法可以達(dá)到這個(gè)目的。(1)每個(gè)對象自己保存自己賬戶類對象在接到“存儲(chǔ)自己”的通知后,知道怎樣把自身存儲(chǔ)起來(需要增加一個(gè)屬性和一個(gè)服務(wù)來定義上述行為)。(2)由數(shù)據(jù)管理子系統(tǒng)負(fù)責(zé)存儲(chǔ)對象賬戶類對象在接到“存儲(chǔ)自己”的通知后,知道應(yīng)該向數(shù)據(jù)管理子系統(tǒng)發(fā)送什么消息,以便由數(shù)據(jù)管理子系統(tǒng)把它的狀態(tài)保存起來,為此也需要增加屬性和服務(wù)來定義上述行為。使用這種方法的優(yōu)點(diǎn),是無須修改問題域子系統(tǒng)。如上一小節(jié)所述,應(yīng)該定義一個(gè)數(shù)據(jù)管理類ObjectServer,并聲明它的對象。這個(gè)類提供下列服務(wù):通知對象保存自身或保存需長期存儲(chǔ)的對象的狀態(tài);檢索已存儲(chǔ)的對象并使之“復(fù)活”。需要綜合考慮對象模型、動(dòng)態(tài)模型和功能模型,才能正確確定類中應(yīng)有的服務(wù)。對象模型是進(jìn)行對象設(shè)計(jì)的基本框架。但是,面向?qū)ο蠓治龅贸龅膶ο竽P?,通常只在每個(gè)類中列出很少幾個(gè)最核心的服務(wù)。設(shè)計(jì)者必須把動(dòng)態(tài)模型中對象的行為以及功能模型中的數(shù)據(jù)處理,轉(zhuǎn)換成由適當(dāng)?shù)念愃峁┑姆?wù)。11.9設(shè)計(jì)類中的服務(wù)

11.9.1設(shè)計(jì)類中應(yīng)有的服務(wù)一張狀態(tài)圖描繪了一類對象的生命周期,圖中的狀態(tài)轉(zhuǎn)換是執(zhí)行對象服務(wù)的結(jié)果。對象的許多服務(wù)都與對象接收到的事件密切相關(guān),事實(shí)上,事件就表現(xiàn)為消息,接收消息的對象必然有由消息選擇符指定的服務(wù),該服務(wù)改變對象狀態(tài)(修改相應(yīng)的屬性值),并完成對象應(yīng)做的動(dòng)作。對象的動(dòng)作既與事件有關(guān),也與對象的狀態(tài)有關(guān)。因此,完成服務(wù)的算法自然也和對象的狀態(tài)有關(guān)。如果一個(gè)對象在不同狀態(tài)可以接受同樣事件,而且在不同狀態(tài)接收到同樣事件時(shí)其行為不同,則實(shí)現(xiàn)服務(wù)的算法中需要有一個(gè)依賴于狀態(tài)的DO-CASE型控制結(jié)構(gòu)。功能模型指明了系統(tǒng)必須提供的服務(wù)。狀態(tài)圖中狀態(tài)轉(zhuǎn)換所觸發(fā)的動(dòng)作,在功能模型中有時(shí)可能擴(kuò)展成一張數(shù)據(jù)流圖。數(shù)據(jù)流圖中的某些處理可能與對象提供的服務(wù)相對應(yīng),下列規(guī)則有助于確定操作的目標(biāo)對象(即應(yīng)該在該對象所屬的類中定義這個(gè)服務(wù)):(1)如果某個(gè)處理的功能是從輸入流中抽取一個(gè)值,則該輸入流就是目標(biāo)對象。(2)如果某個(gè)處理具有類型相同的輸入流和輸出流,而且輸出流實(shí)質(zhì)上是輸入流的另一種形式,則該輸入輸出流就是目標(biāo)對象。(3)如果某個(gè)處理從多個(gè)輸入流得出輸出值,則該處理是輸出類中定義的一個(gè)服務(wù)。(4)如果某個(gè)處理把對輸入流處理的結(jié)果輸出給數(shù)據(jù)存儲(chǔ)或動(dòng)作對象,則該數(shù)據(jù)存儲(chǔ)或動(dòng)作對象就是目標(biāo)對象。當(dāng)一個(gè)處理涉及多個(gè)對象時(shí),為確定把它作為哪個(gè)對象的服務(wù),設(shè)計(jì)者必須判斷哪個(gè)對象在這個(gè)處理中起主要作用。通常在起主要作用的對象類中定義這個(gè)服務(wù)。下面兩條規(guī)則有助于確定處理的歸屬:(1)如果處理影響或修改了一個(gè)對象,則最好把該處理與處理的目標(biāo)(而不是觸發(fā)者)聯(lián)系在一起。(2)考察處理涉及的對象類及這些類之間的關(guān)聯(lián),從中找出處于中心地位的類。如果其他類和關(guān)聯(lián)圍繞這個(gè)中心類構(gòu)成星形,則這個(gè)中心類就是處理的目標(biāo)。在面向?qū)ο笤O(shè)計(jì)過程中還應(yīng)該進(jìn)一步設(shè)計(jì)實(shí)現(xiàn)服務(wù)的方法,主要應(yīng)該完成以下幾項(xiàng)工作。1.設(shè)計(jì)實(shí)現(xiàn)服務(wù)的算法設(shè)計(jì)實(shí)現(xiàn)服務(wù)的算法時(shí),應(yīng)該考慮下列幾個(gè)因素:(1)算法復(fù)雜度。通常選用復(fù)雜度較低(即效率較高)的算法,但也不要過分追求高效率,應(yīng)以能滿足用戶需求為準(zhǔn)。11.9.2設(shè)計(jì)實(shí)現(xiàn)服務(wù)的方法(2)容易理解與容易實(shí)現(xiàn)。容易理解與容易實(shí)現(xiàn)的要求往往與高效率有矛盾,設(shè)計(jì)者應(yīng)該對這兩個(gè)因素適當(dāng)折衷。(3)易修改。應(yīng)該盡可能預(yù)測將來可能做的修改,并在設(shè)計(jì)時(shí)預(yù)先做些準(zhǔn)備。2.選擇數(shù)據(jù)結(jié)構(gòu)在分析階段,僅需考慮系統(tǒng)中需要的信息的邏輯結(jié)構(gòu),在面向?qū)ο笤O(shè)計(jì)過程中,則需要選擇能夠方便、有效地實(shí)現(xiàn)算法的物理數(shù)據(jù)結(jié)構(gòu)。3.定義內(nèi)部類和內(nèi)部操作在面向?qū)ο笤O(shè)計(jì)過程中,可能需要增添一些在需求陳述中沒有提到的類,這些新增加的類,主要用來存放在執(zhí)行算法過程中所得出的某些中間結(jié)果。此外,復(fù)雜操作往往可以用簡單對象上的更低層操作來定義。因此,在分解高層操作時(shí)常常引入新的低層操作。在面向?qū)ο笤O(shè)計(jì)過程中應(yīng)該定義這些新增加的低層操作。在對象模型中,關(guān)聯(lián)是聯(lián)結(jié)不同對象的紐帶,它指定了對象相互間的訪問路徑。在面向?qū)ο笤O(shè)計(jì)過程中,設(shè)計(jì)人員必須確定實(shí)現(xiàn)關(guān)聯(lián)的具體策略。既可以選定一個(gè)全局性的策略統(tǒng)一實(shí)現(xiàn)所有關(guān)聯(lián),也可以分別為每個(gè)關(guān)聯(lián)選擇具體的實(shí)現(xiàn)策略,以與它在應(yīng)用系統(tǒng)中的使用方式相適應(yīng)。為了更好地設(shè)計(jì)實(shí)現(xiàn)關(guān)聯(lián)的途徑,首先應(yīng)該分析使用關(guān)聯(lián)的方式。11.10設(shè)計(jì)關(guān)聯(lián)1.關(guān)聯(lián)的遍歷在應(yīng)用系統(tǒng)中,使用關(guān)聯(lián)有兩種可能的方式:單向遍歷和雙向遍歷。在應(yīng)用系統(tǒng)中,某些關(guān)聯(lián)只需要單向遍歷,這種單向關(guān)聯(lián)實(shí)現(xiàn)起來比較簡單,另外一些關(guān)聯(lián)可能需要雙向遍歷,雙向關(guān)聯(lián)實(shí)現(xiàn)起來稍微麻煩一些。在使用原型法開發(fā)軟件的時(shí)候,原型中所有關(guān)聯(lián)都應(yīng)該是雙向的,以便于增加新的行為,快速地?cái)U(kuò)充和修改原型。2.實(shí)現(xiàn)單向關(guān)聯(lián)用指針可以方便地實(shí)現(xiàn)單向關(guān)聯(lián)。如果關(guān)聯(lián)的重?cái)?shù)是一元的(如圖11.8所示),則實(shí)現(xiàn)關(guān)聯(lián)的指針是一個(gè)簡單指針;如果重?cái)?shù)是多元的,則需要用一個(gè)指針集合實(shí)現(xiàn)關(guān)聯(lián)(參見圖11.9)。圖11.8用指針實(shí)現(xiàn)單向關(guān)聯(lián)圖11.9用指針實(shí)現(xiàn)雙向關(guān)聯(lián)3.實(shí)現(xiàn)雙向關(guān)聯(lián)許多關(guān)聯(lián)都需要雙向遍歷,當(dāng)然,兩個(gè)方向遍歷的頻度往往并不相同。實(shí)現(xiàn)雙向關(guān)聯(lián)有下列3種方法:(1)只用屬性實(shí)現(xiàn)一個(gè)方向的關(guān)聯(lián),當(dāng)需要反向遍歷時(shí)就執(zhí)行一次正向查找。如果兩個(gè)方向遍歷的頻度相差很大,而且需要盡量減少存儲(chǔ)開銷和修改時(shí)的開銷,則這是一種很有效的實(shí)現(xiàn)雙向關(guān)聯(lián)的方法。圖11.10用對象實(shí)現(xiàn)關(guān)聯(lián)(2)兩個(gè)方向的關(guān)聯(lián)都用屬性實(shí)現(xiàn)。具體實(shí)現(xiàn)方法已在前面講過,如圖11.9所示。這種方法能實(shí)現(xiàn)快速訪問,但是,如果修改了一個(gè)屬性,則相關(guān)的屬性也必須隨之修改,才能保持該關(guān)聯(lián)鏈的一致性。當(dāng)訪問次數(shù)遠(yuǎn)遠(yuǎn)多于修改次數(shù)時(shí),這種實(shí)現(xiàn)方法很有效。(3)用獨(dú)立的關(guān)聯(lián)對象實(shí)現(xiàn)雙向關(guān)聯(lián)。關(guān)聯(lián)對象不屬于相互關(guān)聯(lián)的任何一個(gè)類,它是獨(dú)立的關(guān)聯(lián)類的實(shí)例,如圖11.10所示。4.關(guān)聯(lián)對象的實(shí)現(xiàn)可以引入一個(gè)關(guān)聯(lián)類來保存描述關(guān)聯(lián)性質(zhì)的信息,關(guān)聯(lián)中的每個(gè)連接對應(yīng)著關(guān)聯(lián)類的一個(gè)對象。實(shí)現(xiàn)關(guān)聯(lián)對象的方法取決于關(guān)聯(lián)的重?cái)?shù)。對于一對一關(guān)聯(lián)來說,關(guān)聯(lián)對象可以與參與關(guān)聯(lián)的任一個(gè)對象合并。對于一對多關(guān)聯(lián)來說,關(guān)聯(lián)對象可以與“多”端對象合并。如果是多對多關(guān)聯(lián),則關(guān)聯(lián)鏈的性質(zhì)不可能只與一個(gè)參與關(guān)聯(lián)的對象有關(guān),通常用一個(gè)獨(dú)立的關(guān)聯(lián)類來保存描述關(guān)聯(lián)性質(zhì)的信息,這個(gè)類的每個(gè)實(shí)例表示一條具體的關(guān)聯(lián)鏈及該鏈的屬性。系統(tǒng)的各項(xiàng)質(zhì)量指標(biāo)并不是同等重要的,設(shè)計(jì)人員必須確定各項(xiàng)質(zhì)量指標(biāo)的相對重要性(即確定優(yōu)先級),以便在優(yōu)化設(shè)計(jì)時(shí)制定折衷方案。11.11設(shè)計(jì)優(yōu)化

11.11.1確定優(yōu)先級系統(tǒng)的整體質(zhì)量與設(shè)計(jì)人員所制定的折衷方案密切相關(guān)。最終產(chǎn)品成功與否,在很大程度上取決于是否選擇好了系統(tǒng)目標(biāo)。最糟糕的情況是,沒有站在全局高度正確確定各項(xiàng)質(zhì)量指標(biāo)的優(yōu)先級,以致系統(tǒng)中各個(gè)子系統(tǒng)按照相互對立的目標(biāo)做了優(yōu)化,將導(dǎo)致系統(tǒng)資源的嚴(yán)重浪費(fèi)。在折衷方案中設(shè)置的優(yōu)先級應(yīng)該是模糊的。事實(shí)上,不可能指定精確的優(yōu)先級數(shù)值(例如,速度48%,內(nèi)存25%,費(fèi)用8%,可修改性19%)。最常見的情況,是在效率和清晰性之間尋求適當(dāng)?shù)恼壑苑桨?。下面兩小?jié)分別講述在優(yōu)化設(shè)計(jì)時(shí)提高效率的技術(shù),以及建立良好的繼承結(jié)構(gòu)的方法。1.增加冗余關(guān)聯(lián)以提高訪問效率在面向?qū)ο蠓治鲞^程中,應(yīng)該避免在對象模型中存在冗余的關(guān)聯(lián),因?yàn)槿哂嚓P(guān)聯(lián)不僅沒有增添任何信息,反而會(huì)降低模型的清晰程度。但是,在面向?qū)ο笤O(shè)計(jì)過程中,應(yīng)當(dāng)考慮用戶的訪問模式,及不同類型的訪問彼此間的依賴關(guān)系時(shí),就會(huì)發(fā)現(xiàn),分析階段確定的關(guān)聯(lián)可能并沒有構(gòu)成效率最高的訪問路徑。下面用設(shè)計(jì)公司雇員技能數(shù)據(jù)庫的例子,說明分析訪問路徑及提高訪問效率的方法。11.11.2提高效率的幾項(xiàng)技術(shù)圖11.11是從面向?qū)ο蠓治瞿P椭姓〉囊徊糠?。公司類中的服?wù)find_skill返回具有指定技能的雇員集合。例如,用戶可能詢問公司中會(huì)講日語的雇員有哪些人。假設(shè)某公司共有2000名雇員,平均每名雇員會(huì)10種技能,則簡單的嵌套查詢將遍歷雇員對象2000次,針對每名雇員平均再遍歷技能對象10次。如果全公司僅有5名雇員精通日語,則查詢命中率僅有1/4000。圖11.11公司、雇員及技能之間的關(guān)聯(lián)鏈提高訪問效率的一種方法是使用哈希(Hash)表:“具有技能”這個(gè)關(guān)聯(lián)不再利用無序表實(shí)現(xiàn),而是改用哈希表實(shí)現(xiàn)。只要“會(huì)講日語”是用惟一一個(gè)技能對象表示,這樣改進(jìn)后就會(huì)使查詢次數(shù)由20000次減少到2000次。但是,當(dāng)僅有極少數(shù)對象滿足查詢條件時(shí),查詢命中率仍然很低。在這種情況下,更有效的提高查詢效率的改進(jìn)方法是,給那些需要經(jīng)常查詢的對象建立索引。例如,針對上述例子,可以增加一個(gè)額外的限定關(guān)聯(lián)“精通語言”,用來聯(lián)系公司與雇員這兩類對象,如圖11.12所示。利用適當(dāng)?shù)娜哂嚓P(guān)聯(lián),可以立即查到精通某種具體語言的雇員,而無須多余的訪問。當(dāng)然,索引也必然帶來開銷:占用內(nèi)存空間,而且每當(dāng)修改基關(guān)聯(lián)時(shí)也必須相應(yīng)地修改索引。因此,應(yīng)該只給那些經(jīng)常執(zhí)行并且開銷大、命中率低的查詢建立索引。圖11.12為雇員技能數(shù)據(jù)庫建立索引2.調(diào)整查詢次序改進(jìn)了對象模型的結(jié)構(gòu),從而優(yōu)化了常用的遍歷之后,接下來就應(yīng)該優(yōu)化算法了。優(yōu)化算法的一個(gè)途徑是盡量縮小查找范圍。例如,假設(shè)用戶在使用上述的雇員技能數(shù)據(jù)庫的過程中,希望找出既會(huì)講日語又會(huì)講法語的所有雇員。如果某公司只有5位雇員會(huì)講日語,會(huì)講法語的雇員卻有200人,則應(yīng)該先查找會(huì)講日語的雇員,然后再從這些會(huì)講日語的雇員中查找同時(shí)又會(huì)講法語的人。3.保留派生屬性通過某種運(yùn)算而從其

溫馨提示

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

評論

0/150

提交評論