软件工程(总体设计②设计原理)
設(shè)計(jì)原理
模塊化
模塊是由邊界元素限定的相鄰程序元素的序列,而且有一個(gè)總體標(biāo)識(shí)符代表它。
按照模塊的定義,過(guò)程、函數(shù)、子程序和宏,都可作為模塊。
面向?qū)ο蠓椒▽W(xué)中的對(duì)象是模塊,對(duì)象內(nèi)的方法也是模塊。模塊是構(gòu)成程序的基本構(gòu)件。
模塊化就是把程序劃分成獨(dú)立命名且可獨(dú)立訪問(wèn)的模塊,每個(gè)模塊完成一個(gè)子功能,把這些模塊集成起來(lái)構(gòu)成一個(gè)整體,可以完成指定的功能滿足用戶的需求
當(dāng)模塊數(shù)目增加時(shí)每個(gè)模塊的規(guī)模將減小,開發(fā)單個(gè)模塊需要的成本確實(shí)減少了,但是,隨著模塊數(shù)目的增加,設(shè)計(jì)模塊間接口所需要的工作量也將增加,根據(jù)這兩個(gè)因素,得出圖中的總成本曲線。
每個(gè)程序都相應(yīng)地有一個(gè)最適當(dāng)?shù)哪K數(shù)目M,使得系統(tǒng)的開發(fā)成本最小,雖然目前還不能精確地決定M的數(shù)值,但是在考慮模塊化的時(shí)候總成本曲線確實(shí)是有也的指南。
采用模塊化原理可以使軟件結(jié)構(gòu)清晰,不僅容易設(shè)計(jì)也容易閱讀和理解。
抽象
人類在認(rèn)識(shí)復(fù)雜現(xiàn)象的過(guò)程中使用的最強(qiáng)有力的思維工具是抽象。人們?cè)趯?shí)踐中認(rèn)識(shí)到,在現(xiàn)實(shí)世界中一定事物、狀態(tài)或過(guò)程之間總存在著某些相似的方面(共性)。把這些相似的方面集中和概括起來(lái),暫時(shí)忽略它們之間的差異,這就是抽象。或者說(shuō)抽象就是抽出事物的本質(zhì)特性而暫時(shí)不考慮它們的細(xì)節(jié)。
由于人類思維能力的限制,如果每次面臨的因素太多,是不可能產(chǎn)生精確思維的。處理復(fù)雜系統(tǒng)的唯有效的方法是用層次的方式構(gòu)造和分析它。一個(gè)復(fù)雜的動(dòng)態(tài)系統(tǒng)首先可以用一些高級(jí)的抽象概念構(gòu)造和理解.這些高級(jí)概念又可以用一些較低級(jí)的概念構(gòu)造和理解,如此進(jìn)行下去,直至最低層次的具體元素。
這種層次的思維和解題方式必須反映在定義動(dòng)態(tài)系統(tǒng)的程序結(jié)構(gòu)之中,每級(jí)的一個(gè)概念將以某種方式對(duì)應(yīng)于程序的一組成分。當(dāng)考慮對(duì)任何問(wèn)題的模塊化解法時(shí),可以提出許多抽象的層次。在抽象的最高層次使用問(wèn)題環(huán)境的語(yǔ)言,以概括的方式敘述問(wèn)題的解法;在較低抽象層次采用更過(guò)程化的方法,把面向問(wèn)題的術(shù)語(yǔ)和面向?qū)崿F(xiàn)的術(shù)語(yǔ)結(jié)合起來(lái)敘述問(wèn)題的解法;最后,在最低的抽象層次用可以直接實(shí)現(xiàn)的方式敘述問(wèn)題的解法。
軟件工程過(guò)程的每一步都是對(duì)軟件解法的抽象層次的一次精化。在可行性研究階段,軟件作為系統(tǒng)的一個(gè)完整部件:在需求分析期間,軟件解法是使用在問(wèn)題環(huán)境內(nèi)熟悉的方式描述的:當(dāng)由總體設(shè)計(jì)向詳細(xì)設(shè)計(jì)過(guò)渡時(shí),抽象的程度也就隨之減少了;最后,當(dāng)源程序?qū)懗鰜?lái)以后,也就達(dá)到了抽象的最低層。
逐步求精和模塊化的概念,與抽象是緊密相關(guān)的。隨著軟件開發(fā)工程的進(jìn)展,在軟件結(jié)構(gòu)每層中的模塊,表示了對(duì)軟件抽象層次的一次精化。事實(shí)上,軟件結(jié)構(gòu)頂層的模塊,控制了系統(tǒng)的主要功能并且影響全局:在軟件結(jié)構(gòu)底層的模塊,完成對(duì)數(shù)據(jù)的一個(gè)具體處理。用自頂向下由抽象到具體的方式分配控制,簡(jiǎn)化了軟件的設(shè)計(jì)和實(shí)現(xiàn),提高了軟件的可理解性和可測(cè)試性,并且使軟件更容易維護(hù)。
逐步求精
逐步求精是人類解決復(fù)雜問(wèn)題時(shí)采用的基本方法,也是許多軟件工程技術(shù)(例如,規(guī)格說(shuō)明技術(shù),設(shè)計(jì)和實(shí)現(xiàn)技術(shù))的基礎(chǔ)。可以把逐步求精定義為:“為了能集中精力解決主要問(wèn)題而盡量推遲對(duì)問(wèn)題細(xì)節(jié)的考慮。”
逐步求精之所以如此重要,是因?yàn)槿祟惖恼J(rèn)知過(guò)程遵守Miller 法則:一個(gè)人在任何時(shí)候都只能把注意力集中在(7土2)個(gè)知識(shí)塊上。
但是,在開發(fā)軟件的過(guò)程中,軟件工程師在一段時(shí)間內(nèi)需 要考慮的知識(shí)塊數(shù)遠(yuǎn)遠(yuǎn)多于7。例如,一個(gè)程序通常不止使用7個(gè)數(shù)據(jù),一個(gè)用戶也往往有不止7個(gè)方面的需求。逐步求精方法的強(qiáng)大作用就在于,它能幫助軟件工程師把精力集中在與當(dāng)前開發(fā)階段最相關(guān)的那些方面上,而忽略那些對(duì)整體解決方案來(lái)說(shuō)雖然是必要的,然而目前還不需要考慮的細(xì)節(jié).這些細(xì)節(jié)將留到以后再考慮。Miller 法則是人類智力的基本局限,人們不可能戰(zhàn)勝自己的自然本性,只能接受這個(gè)事實(shí),承認(rèn)自身的局限性,并在這個(gè)前提下盡自己的最大努力工作。
事實(shí)上,可以把逐步求精看作是項(xiàng)把一個(gè)時(shí)期內(nèi)必須解決的種種問(wèn)題按優(yōu)先級(jí)排序的技術(shù)。逐步求精方法確保每個(gè)問(wèn)題都將被解決,而且每個(gè)問(wèn)題都將在適當(dāng)?shù)臅r(shí)候被解決,但是,在任何時(shí)候一個(gè)人都不需要同時(shí)處理7個(gè)以上知識(shí)塊。逐步求精最初是由Niklaus Wirth提出的種自頂向下的設(shè)計(jì)策略。按照這種設(shè)計(jì)策略,程序的體系結(jié)構(gòu)是通過(guò)逐步精化處理過(guò)程的層次而設(shè)計(jì)出來(lái)的。通過(guò)逐步分解對(duì)功能的宏觀陳述而開發(fā)出層次結(jié)構(gòu),直至最終得出用程序設(shè)計(jì)語(yǔ)盲表達(dá)的程序。
Wirth本人對(duì)逐步求精策略曾做過(guò)如下的概括說(shuō)明。“我們對(duì)付復(fù)雜問(wèn)題的最重要的辦法是抽象,因此,對(duì)一個(gè)復(fù)雜的問(wèn)題不應(yīng)該立刻用計(jì)算機(jī)指令、數(shù)字和邏輯符號(hào)來(lái)表示,而應(yīng)該用較自然的抽象語(yǔ)句來(lái)表示,從而得出抽象程序。抽象程序?qū)Τ橄蟮臄?shù)據(jù)進(jìn)行某些特定的運(yùn)算并用某些合適的記號(hào)(可能是自然語(yǔ)言)來(lái)表示。對(duì)抽象程序做進(jìn)一步的分解,并進(jìn)入下 一個(gè)抽象層次,這樣的精細(xì)化過(guò)程一直進(jìn)行下去,直到程序能被計(jì)算機(jī)接受為止。這時(shí)的程序可能是用某種高級(jí)語(yǔ)言或機(jī)器指令書寫的。”
求精實(shí)際上是細(xì)化過(guò)程。
人們從在高抽象級(jí)別定義的功能陳述(或信息措述)開始,也就是說(shuō),該陳述僅僅概念性地描述了功能或信息,但是并沒有提供功能的內(nèi)部工作情況或信息的內(nèi)部結(jié)構(gòu)。求精要求設(shè)計(jì)者細(xì)化原始陳述,隨著每個(gè)后續(xù)求精(即細(xì)化)步驟的完成而提供越來(lái)越多的細(xì)節(jié)。
抽象與求精是對(duì)互補(bǔ)的概念。
抽象使得設(shè)計(jì)者能夠說(shuō)明過(guò)程和數(shù)據(jù),同時(shí)卻忽略了低層細(xì)節(jié)。事實(shí)上,可以把抽象看作是一種通過(guò)忽略多余的細(xì)節(jié)同時(shí)強(qiáng)調(diào)有關(guān)的細(xì)節(jié),而實(shí)現(xiàn)逐步求精的方法。求精則幫助設(shè)計(jì)者在設(shè)計(jì)過(guò)程中逐步揭示出低層細(xì)節(jié)。這兩個(gè)概念都有助于設(shè)計(jì)者在設(shè)計(jì)演化過(guò)程中創(chuàng)造出完整的設(shè)計(jì)模型。
信息隱藏和局部化
應(yīng)用模塊化原理時(shí),自 然會(huì)產(chǎn)生的一個(gè)問(wèn)題是:“為了得到最好的-組模塊,應(yīng)該怎樣分解軟件呢?”信息隱藏原理指出:應(yīng)該這樣設(shè)計(jì)和確定模塊,使得一個(gè)模塊內(nèi)包含的信息(過(guò)程和數(shù)據(jù))對(duì)于不需要這些信息的模塊來(lái)說(shuō),是不能訪問(wèn)的。局部化的概念和信息隱藏概念是密切相關(guān)的。所謂局部化是指把些 關(guān)系密切的軟件元素物理地放得彼此靠近。在模塊中使用局部數(shù)據(jù)元素是局部化的一個(gè)例子。顯然。局部化有助于實(shí)現(xiàn)信息隱藏。
實(shí)際上,應(yīng)該隱藏的不是有關(guān)模塊的切信息,而是 模塊的實(shí)現(xiàn)細(xì)節(jié)。 因此,有人主張把這條原理稱為“細(xì)節(jié)胞藏”。在“隱藏”意味著有效的模塊化可以通過(guò)定又 一組獨(dú)立的模塊面實(shí)現(xiàn),這些獨(dú)立的模塊彼此間僅僅交換那些為了完成系統(tǒng)功能而必須交換的信息。如果在測(cè)試期間和以后的軟件維護(hù)期間需要修改軟件,那么使用信息隱藏原理作為模塊化系統(tǒng)設(shè)計(jì)的標(biāo)準(zhǔn)就會(huì)帶來(lái)極大好處。因?yàn)榻^大多數(shù)數(shù)據(jù)和過(guò)程對(duì)于軟件的其他部分面言是隱藏的(也就是“看”不見的),在修改期間由于疏忽面引人的錯(cuò)誤就很少可能傳播到軟件的其他部分。
模塊獨(dú)立
模塊獨(dú)立的概念是模塊化抽象、信息隱藏和局部化概念的直接結(jié)果。
開發(fā)具有獨(dú)立功能面且和其他模塊之間沒有過(guò)多的相互作用的模塊,就可以做到模塊獨(dú)立。換句話說(shuō),希望這樣設(shè)計(jì)軟件結(jié)構(gòu),使得每個(gè)模塊完成一個(gè) 相對(duì)獨(dú)立的特定子功能,并且和其他模塊之間的關(guān)系很簡(jiǎn)單。
為什么模塊的獨(dú)立性很重要呢?主要有兩條理由:
第一,有效的模塊化(即具有獨(dú)立的模塊)的軟件比較容易開發(fā)出來(lái)。這是由于能夠分割功能而且接口可以簡(jiǎn)化.當(dāng)許多人分工合作開發(fā)同一個(gè)軟件時(shí),這個(gè)優(yōu)點(diǎn)尤其重要。
第二,獨(dú)立的模塊比較容易測(cè)試和維護(hù)。這是因?yàn)橄鄬?duì)說(shuō)來(lái),修改設(shè)計(jì)和程序需要的工作量比較小,錯(cuò)誤傳播范圍小,需要擴(kuò)充功能時(shí)能夠“插入”模塊。總之,模塊獨(dú)立是好設(shè)計(jì)的關(guān)鍵,而設(shè)計(jì)又是決定軟件質(zhì)量的關(guān)鍵環(huán)節(jié)。
模塊的獨(dú)立程度可以由兩個(gè)定性標(biāo)準(zhǔn)度量,這兩個(gè)標(biāo)準(zhǔn)分別稱為內(nèi)聚和耦合。耦合衡量不同模塊彼此間互相依賴(連接)的緊密程度:內(nèi)聚衡量一個(gè)模塊內(nèi)部各個(gè)元素彼此結(jié)合的緊密程度。以下分別詳細(xì)闡述。
1.耦合
耦合是對(duì)一個(gè)軟件結(jié)構(gòu)內(nèi)不同模塊之間互連程度的度量。桐合強(qiáng)弱取決于模塊間接口的復(fù)雜程度,進(jìn)人或訪問(wèn)一個(gè)模塊的點(diǎn),以及通過(guò)接口的數(shù)據(jù)。
在軟件設(shè)計(jì)中應(yīng)該追求盡可能松散耦合的系統(tǒng)。在這樣的系統(tǒng)中可以研究、測(cè)試或維護(hù)任何一個(gè)模塊,而不需要對(duì)系統(tǒng)的其他模塊有很多了解。此外,由于模塊間聯(lián)系簡(jiǎn)單,發(fā)生在一處的錯(cuò)誤傳播到整個(gè)系統(tǒng)的可能性就很小。因此,模塊間的耦合程度強(qiáng)烈影響著系統(tǒng)的可理解性、可測(cè)試性、可靠性和可維護(hù)性。
怎樣具體區(qū)分模塊間耦合程度的強(qiáng)弱呢?
如果兩個(gè)模塊中的每一個(gè)都能獨(dú)立地工作而不需要另一個(gè)模塊的存在,那么它們彼此完全獨(dú)立.這意味著模塊間無(wú)任何連接,概合程度最低。但是,在一個(gè)軟件系統(tǒng)中不可能所有模塊之間都沒有任何連接。
如果兩個(gè)模塊彼此間通過(guò)參數(shù)交換信息,而且交換的信息僅僅是數(shù)據(jù),那么這種耦合稱為數(shù)據(jù)耦合。如果傳遞的信息中有控制信息(盡管有時(shí)這種控制信息以數(shù)據(jù)的形式出現(xiàn)),則這種耦合稱為控制耦合。
數(shù)據(jù)耦合是低耦合。系統(tǒng)中至少必須存在這種耦合,因?yàn)橹挥挟?dāng)某些模塊的輸出數(shù)據(jù)作為另一些模塊的輸人數(shù)據(jù)時(shí),系統(tǒng)才能完成有價(jià)值的功能。一般說(shuō)來(lái),一個(gè)系統(tǒng)內(nèi)可以只包含數(shù)據(jù)耦合。控制耦合是中等度的耦合,它增加了系統(tǒng)的復(fù)雜程度。控制耦合往往是多余的,在把模塊適當(dāng)分解之后通常可以用數(shù)據(jù)耦合代替它。
如果被調(diào)用的模塊需要使用作為參數(shù)傳遞進(jìn)來(lái)的數(shù)據(jù)結(jié)構(gòu)中的所有元素,那么,把整個(gè)數(shù)據(jù)結(jié)構(gòu)作為參數(shù)傳遞就是完全正確的。但是,當(dāng)把整個(gè)數(shù)據(jù)結(jié)構(gòu)作為參數(shù)傳遞而被調(diào)用的模塊只需要使用其中一部分?jǐn)?shù)據(jù)元素時(shí),就出現(xiàn)了特征耦合。在這種情況下,被調(diào)用的模塊可以使用的數(shù)據(jù)多于它確實(shí)需要的數(shù)據(jù),這將導(dǎo)致對(duì)數(shù)據(jù)的訪問(wèn)失去控制,從而給計(jì)算機(jī)犯罪提供了機(jī)會(huì)。
當(dāng)兩個(gè)或多個(gè)模塊通過(guò)一個(gè)公 共數(shù)據(jù)環(huán)境相互作用時(shí),它們之間的耦合稱為公共環(huán)境耦合。公共環(huán)境可以是全程變量、共享的通信區(qū)、內(nèi)存的公共覆蓋區(qū)、任何存儲(chǔ)介質(zhì)上的文件、物理設(shè)備等。
公共環(huán)境耦合的復(fù)雜程度隨耦合的模塊個(gè)數(shù)而變化,當(dāng)耦合的模塊個(gè)數(shù)增加時(shí)復(fù)雜程度顯著增加。如果只有兩個(gè)模塊有公共環(huán)境,那么這種耦合有下面兩種可能。
(1)一個(gè)模塊往公共環(huán)境送數(shù)據(jù),另一個(gè)模塊從公共環(huán)境取數(shù)據(jù)。這是數(shù)據(jù)耦合的一種形式,是比較松散的耦合。
(2)兩個(gè)模塊都既往公共環(huán)境送數(shù)據(jù)又從里面取數(shù)據(jù),這種耦合比較緊密,介于數(shù)據(jù)耦合和控制耦合之間。如果兩個(gè)模塊共享的數(shù)據(jù)很多,都通過(guò)參數(shù)傳遞可能很不方便,這時(shí)可以利用公共環(huán)境耦合。
最高程度的耦合是內(nèi)容耦合。如果出現(xiàn)下列情況之一, 兩個(gè)模塊間就發(fā)生了內(nèi)容耦合
1、一個(gè)模塊訪問(wèn)另一個(gè)模塊的內(nèi)部數(shù)據(jù)。
2、一個(gè)模塊不通過(guò)正常人口而轉(zhuǎn)到另一個(gè)模塊的內(nèi)部。
3、兩個(gè)模塊有一部分程序代碼重疊(只可能出現(xiàn)在匯編程序中)。
4、一個(gè)模塊有多個(gè)人口(這意味著一個(gè)模塊有幾種功能)。
應(yīng)該堅(jiān)決避免使用內(nèi)容耦合。事實(shí)上許多高級(jí)程序設(shè)計(jì)語(yǔ)言已經(jīng)設(shè)計(jì)成不允許在程序中出現(xiàn)任何形式的內(nèi)容耦合。
總之,耦合是影響軟件復(fù)雜程度的一個(gè)重要因素。應(yīng)該采取下述設(shè)計(jì)原則:盡量使用數(shù)據(jù)耦合,少用控制耦合和特征耦合,限制公共環(huán)境耦合的范圍,完全不用內(nèi)容耦合。
2.內(nèi)聚
內(nèi)聚標(biāo)志著一個(gè)模塊內(nèi)各個(gè)元素彼此結(jié)合的緊密程度,它是信息隱藏和局部化概念的自然擴(kuò)展。簡(jiǎn)單地說(shuō),理想內(nèi)聚的模塊只做一件事情 。設(shè)計(jì)時(shí)應(yīng)該力求做到高內(nèi)聚,通常中等程度的內(nèi)聚也是可以采用的,而且效果和高內(nèi)聚相差不多。內(nèi)聚和耦合是密切相關(guān)的,模塊內(nèi)的高內(nèi)聚往往意味著模塊間的松耦合。內(nèi)聚和耦合都是進(jìn)行模塊化設(shè)計(jì)的有力工具,但是實(shí)踐表明內(nèi)聚更重要,應(yīng)該把更鄉(xiāng)注意力集中到提高模塊的內(nèi)聚程度上。
低內(nèi)聚有如下兒類:如果-個(gè)模塊完成一組任務(wù),這些任務(wù)彼此間即使有關(guān)系,關(guān)系也是很松散的,就叫做偶然內(nèi)聚。有時(shí)在寫完一個(gè)程序之后,發(fā)現(xiàn) 組語(yǔ)句在兩處成多處出現(xiàn),于是把這些語(yǔ)句作為個(gè)模塊以節(jié) 省內(nèi)存.這樣就出現(xiàn)了偶然內(nèi)聚的模塊。如果一個(gè)模塊完成的任務(wù)在邏輯上屬于相同或相似的一類(例如 個(gè)模塊產(chǎn)生 各種類型的全部輸出)則稱為邏輯內(nèi)聚。如果一個(gè)模塊包含的任務(wù)必須在同一段時(shí)間內(nèi)執(zhí)行(例如,模塊完成各種初始化工作),就叫時(shí)間內(nèi)聚。
在偶然內(nèi)聚的模塊中,各種元素之間沒有實(shí)質(zhì)性聯(lián)系,很可能在一種應(yīng)用場(chǎng)合需要 修改這個(gè)模塊,而在另種應(yīng)用場(chǎng)合又不允許這種修改,從而陷人困境。 事實(shí)上,偶然內(nèi)聚
的模塊出現(xiàn)修改錯(cuò)誤的概率比其他類型的模塊高得多。
在邏輯內(nèi)聚的模塊中,不同功能混在一起,合用部分程序代碼即使局部功能的修改有時(shí)也會(huì)影響全局。因此,這類模塊的修改也比較困難。
時(shí)間關(guān)系在一定程度上反映了程序的某些實(shí)質(zhì),所以時(shí)間內(nèi)聚比邏輯內(nèi)聚好一些。中內(nèi)聚主要有兩類:如果一個(gè)模塊內(nèi)的處理元素是相關(guān)的,而且必須以特定次序執(zhí)行,則稱為過(guò)程內(nèi)聚。使用程序流程圖作為工具設(shè)計(jì)軟件時(shí),常常通過(guò)研究流程圖確定模塊的劃分,這樣得到的往往是過(guò)程內(nèi)聚的模塊。如果模塊中所有元素都使用同一個(gè)輸人數(shù)據(jù)和(或)產(chǎn)生同一個(gè)輸出數(shù)據(jù),則稱為通信內(nèi)聚。
高內(nèi)聚也有兩類:如果一個(gè)模塊內(nèi)的處理元素和同一個(gè)功能密切相關(guān),而且這此處理必須順序執(zhí)行(通常一個(gè)處理元素的輸出數(shù)據(jù)作為下一個(gè)處理元素的輸人數(shù)據(jù)),則稱為順序內(nèi)聚。根據(jù)數(shù)據(jù)流圖劃分模塊時(shí),通常得到順序內(nèi)聚的模塊,這種模塊彼此間的連接往往比較簡(jiǎn)單。如果模塊內(nèi)所有處理元素屬于一個(gè)整體,完成一個(gè)單一的功能,則稱為功能內(nèi)聚。功能內(nèi)聚是最高程度的內(nèi)聚。
耦合和內(nèi)聚的概念是Constantine, Yourdon,Myers和Stevens等人提出來(lái)的。按照他們的觀點(diǎn),如果給上述7種內(nèi)聚的優(yōu)劣評(píng)分,將得到如下結(jié)果:
功能內(nèi)聚10 分??? 時(shí)間內(nèi)聚3 分
順序內(nèi)聚9 分????? 邏輯內(nèi)聚1 分
通信內(nèi)聚7 分????? 偶然內(nèi)聚0 分
過(guò)程內(nèi)聚5 分
事實(shí)上,沒有必要精確確定內(nèi)聚的級(jí)別。重要的是設(shè)計(jì)時(shí)力爭(zhēng)做到高內(nèi)聚,并且能夠辨認(rèn)出低內(nèi)聚的模塊,有能力通過(guò)修改設(shè)計(jì)提高模塊的內(nèi)聚程度并且降低模塊間的耦合程度,從而獲得較高的模塊獨(dú)立性。
總結(jié)
以上是生活随笔為你收集整理的软件工程(总体设计②设计原理)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 美团生活费多久提额
- 下一篇: 儿童吹泡泡水简单配方_儿童吹泡泡玩具水怎