版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
軟件工程思想軟件工程思想軟件工程思想第五章系統(tǒng)設(shè)計(jì)系統(tǒng)設(shè)計(jì)是把需求轉(zhuǎn)化為軟件系統(tǒng)的最重要的環(huán)節(jié)。系統(tǒng)設(shè)計(jì)的優(yōu)劣在根本上決定了軟件系統(tǒng)的質(zhì)量。就象“一切帝國主義都是紙老虎”那樣可以斷定“差的系統(tǒng)設(shè)計(jì)必定產(chǎn)生差的軟件系統(tǒng)?!彼晕覀円ΡWC系統(tǒng)設(shè)計(jì)“根正苗紅”,把一切左傾、右傾的設(shè)計(jì)思潮消滅在萌芽狀態(tài)。WindowsNT的一位系統(tǒng)設(shè)計(jì)師擁有8輛法拉利跑車,讓Microsoft公司的一些程序員十分眼紅。但你只能羨慕而不能憤恨,因?yàn)椴⒉皇敲總€(gè)程序員都有本事成為復(fù)雜軟件系統(tǒng)的設(shè)計(jì)師。系統(tǒng)設(shè)計(jì)要比純粹的編程困難得多。即便你清楚客戶的需求,卻未必知道應(yīng)該設(shè)計(jì)什么樣的軟件系統(tǒng)——既能掙最多的錢又能讓客戶滿意?!疤煜挛骱?,最美是杭州”,千年前蘇東坡大學(xué)士對西湖精采絕倫的系統(tǒng)設(shè)計(jì),使杭州榮升為“天堂”,讓后人只剩下贊嘆和破壞的份了。本章講述系統(tǒng)設(shè)計(jì)的四方面內(nèi)容:體系結(jié)構(gòu)設(shè)計(jì)、模塊設(shè)計(jì)、數(shù)據(jù)結(jié)構(gòu)與算法設(shè)計(jì)、用戶界面設(shè)計(jì)。如果將軟件系統(tǒng)比喻為人體,那么:(1)體系結(jié)構(gòu)就如同人的骨架。如果某個(gè)家伙的骨架是猴子,那么無論怎樣喂養(yǎng)和美容,這家伙始終都是猴子,不會成為人。(2)模塊就如同人的器官,具有特定的功能。人體中最出色的模塊設(shè)計(jì)之一是手,手只有幾種動(dòng)作,卻能做無限多的事情。人體中最糟糕的模塊設(shè)計(jì)之一是嘴巴,嘴巴將最有價(jià)值但毫無相干的幾種功能如吃飯、說話、親吻混為一體,使之無法并行處理,真乃人類之不幸。(3)數(shù)據(jù)結(jié)構(gòu)與算法就如同人的血脈和神經(jīng),它讓器官具有生命并能發(fā)揮功能。數(shù)據(jù)結(jié)構(gòu)與算法分布在體系結(jié)構(gòu)和模塊中,它將協(xié)調(diào)系統(tǒng)的各個(gè)功能。人的耳朵和嘴巴雖然是相對獨(dú)立的器官,但如果耳朵失聰了,嘴巴就只能發(fā)出“啊”“嗚”的聲音,等于喪失了說話的功能(所以聾子天生就是啞巴),可人們卻又能用手勢代替說話。人體的數(shù)據(jù)結(jié)構(gòu)與算法設(shè)計(jì)真是十分神奇并且十分可笑。(4)用戶界面就如同人的外表,最容易讓人一見鐘情或一見惡心。象人類追求心靈美和外表美那樣,軟件系統(tǒng)也追求(內(nèi)在的)功能強(qiáng)大和(外表的)界面友好。但隨著生活節(jié)奏的加快,人們已少有興趣去品味深藏不露的內(nèi)在美。如果把Unix系統(tǒng)比作是健壯的漢子和婦人,那么Windows系統(tǒng)就象嫵媚的小白臉和狐貍精。想不到Windows系統(tǒng)竟然能興風(fēng)作浪,占去大半市場。有鑒于此,我們應(yīng)該鼓勵(lì)女士多買化妝品(男士付錢)以獲得更好的界面。在進(jìn)行系統(tǒng)設(shè)計(jì)時(shí),我們要深情地關(guān)注軟件的質(zhì)量因素,如正確性與精確性、性能與效率、易用性、可理解性與簡法性、可復(fù)用性與可擴(kuò)充性等等。即使把系統(tǒng)設(shè)計(jì)做好了,也并不意味著就能產(chǎn)生好的軟件系統(tǒng)。在程序設(shè)計(jì)、測試、維護(hù)等環(huán)節(jié)還要做大量的工作,無論哪個(gè)環(huán)節(jié)出了差錯(cuò),都會把好事搞砸了。據(jù)說上帝把所有的女士都設(shè)計(jì)成天使,可是天使們在下凡時(shí)有些雙腳先著地,有些臉先著地。上帝的這一疏忽讓很多女孩傷透了心。我們在開發(fā)軟件時(shí),一定要吸取這個(gè)教訓(xùn)。體系結(jié)構(gòu)設(shè)計(jì)楊叔子院子曾這樣指點(diǎn)其弟子:文學(xué)中有科學(xué),音樂中有數(shù)學(xué),漫畫中有現(xiàn)代數(shù)學(xué)的拓?fù)鋵W(xué)。漫畫家可以“幾筆”就把一個(gè)人畫出來,不管怎么美化或丑化,就是活像。為什么因?yàn)槟恰皫坠P”不是別的,而是拓?fù)鋵W(xué)中的特征不變量,這是事物最本質(zhì)的東西。體系結(jié)構(gòu)是軟件系統(tǒng)中最本質(zhì)的東西:(1)體系結(jié)構(gòu)是對復(fù)雜事物的一種抽象。良好的體系結(jié)構(gòu)是普遍適用的,它可以高效地處理多種多樣的個(gè)體需求。一提起“房子”,我們的腦中馬上就會出現(xiàn)房子的印象(而不是地洞的印象)。“房子”是人們對住宿或辦公環(huán)境的一種抽象。不論是辦公樓還是民房,同一類建筑物(甚至不同類的建筑物)之間都具有非常相似的體系結(jié)構(gòu)和構(gòu)造方式。如果13億中國人民每個(gè)人都要用特別的方式構(gòu)造奇異的房子,那么960萬平方公里的土地將會變得千瘡百孔,終日不得安寧。(2)體系結(jié)構(gòu)在一定的時(shí)間內(nèi)保持穩(wěn)定。只有在穩(wěn)定的環(huán)境下,人們才能干點(diǎn)事情,社會才能發(fā)展??茖W(xué)告訴我們,宇宙間萬物無時(shí)無刻不在運(yùn)動(dòng)、飛行。由于我們的生活環(huán)境在地球上保持相對穩(wěn)定,以致于我們可以無憂無慮地吃飯和睡覺,壓根就意識不到自己是活生生的導(dǎo)彈。軟件開發(fā)最怕的就是需求變化,但“需求會發(fā)生變化”是個(gè)無法逃避的現(xiàn)實(shí)。人們希望在需求發(fā)生變化時(shí),最好只對軟件做些皮皮毛毛的修改,可千萬別改動(dòng)軟件的體系結(jié)構(gòu)。就如人們對住宿的需求也會變動(dòng),你可以經(jīng)常改變房間的裝璜和擺設(shè),但不會在每次變動(dòng)時(shí)都要去折墻、拆柱、挖地基。如果當(dāng)需求發(fā)生變化時(shí),程序員不得不去修改軟件的體系結(jié)構(gòu),那么這個(gè)軟件的系統(tǒng)設(shè)計(jì)是失敗的。良好的體系結(jié)構(gòu)意味著普適、高效和穩(wěn)定。本節(jié)將論述兩種非常通用的軟件體系結(jié)構(gòu):層次結(jié)構(gòu)和客戶機(jī)/服務(wù)器(Client/Server)結(jié)構(gòu)。層次結(jié)構(gòu)層次結(jié)構(gòu)表達(dá)了這么一種常識:有些事情比較復(fù)雜,我們沒法一口氣干完,就把事情分為好幾層,一層一層地去做。高層的工作總是建立在低層的工作之上。層次關(guān)系主要有兩種:上下級關(guān)系和順序相鄰關(guān)系。一、上下級關(guān)系的層次結(jié)構(gòu)我們從小學(xué)一直讀到博士研究生畢業(yè),要讀20多年,可以分為五個(gè)層次。而范進(jìn)的知識結(jié)構(gòu)只有兩層:“私塾”和“秀才”,但讀了五十多年,如圖所示。一般地處于較高層次的學(xué)生應(yīng)該懂得所有低層次的知識,而處于低層次學(xué)生無法懂得所有高層次的知識。圖的層次結(jié)構(gòu)存在上下級關(guān)系,如同在軍隊(duì)中,上級可以命令下級,而下級不能命令上級。如果把圖的層次結(jié)構(gòu)當(dāng)成是一個(gè)軟件系統(tǒng)的結(jié)構(gòu),那么上層子系統(tǒng)可以使用下層子系統(tǒng)的功能,而下層子系統(tǒng)不能夠使用上層子系統(tǒng)的功能。二、順序相鄰關(guān)系的層次結(jié)構(gòu)順序相鄰關(guān)系的層次結(jié)構(gòu)表明通訊只能在相鄰兩層之間發(fā)生,信息只能被一層一層地順序傳遞。這種層次結(jié)構(gòu)的經(jīng)典之作是計(jì)算機(jī)網(wǎng)絡(luò)的OSI參考模型,如圖所示。為了減少設(shè)計(jì)的復(fù)雜性,大多數(shù)網(wǎng)絡(luò)都按層(Layer)或級(Level)的方式組織。每一層的目的都是向它的上一層提供一定的服務(wù),而把如何實(shí)現(xiàn)這一服務(wù)的細(xì)節(jié)對上一層加以屏蔽。一臺機(jī)器上的第n層與另一臺機(jī)器上的第n層進(jìn)行對話。通話的規(guī)則就是第n層的協(xié)議。數(shù)據(jù)不是從一臺機(jī)器的第n層直接傳送到另一臺機(jī)器的第n層。發(fā)送方把數(shù)據(jù)和控制信息逐層向下傳遞。最低層是物理介質(zhì),它進(jìn)行實(shí)際的通訊。接收方則將數(shù)據(jù)和控制信息逐層向上傳遞。每一對相鄰層之間都有接口。接口定義了下層提供的原語操作和服務(wù)。當(dāng)網(wǎng)絡(luò)設(shè)計(jì)者在決定一個(gè)網(wǎng)絡(luò)應(yīng)包含多少層,每一層應(yīng)當(dāng)做什么的時(shí)候,其中很重要的工作是在相鄰層之間定義清晰的接口。接口可以使得同一層能輕易地用某一種實(shí)現(xiàn)(Implementation)來替換另一種完全不同的實(shí)現(xiàn)(如用衛(wèi)星信道來代替所有的電話線),只要新的實(shí)現(xiàn)能向上層提供同一組服務(wù)就可以了。[Tanenbaum1998]小小學(xué)(5-6年)碩碩士(2-3年)考上“舉人”時(shí)已五十多歲了本科(4年)復(fù)習(xí)報(bào)考“本科(4年)中學(xué)(6年)中學(xué)(6年)私塾秀才博士(3-4年)圖(a)從小學(xué)讀到博士存在的五個(gè)學(xué)習(xí)階段圖(b)范進(jìn)的知識結(jié)構(gòu)主機(jī)A數(shù)據(jù)鏈路層網(wǎng)絡(luò)層傳輸層會話層表示層應(yīng)用層數(shù)據(jù)鏈路層網(wǎng)絡(luò)層傳輸層會話層表示層應(yīng)用層物理層舉人主機(jī)B主機(jī)A數(shù)據(jù)鏈路層網(wǎng)絡(luò)層傳輸層會話層表示層應(yīng)用層數(shù)據(jù)鏈路層網(wǎng)絡(luò)層傳輸層會話層表示層應(yīng)用層物理層舉人主機(jī)B物理層圖計(jì)算機(jī)網(wǎng)絡(luò)的OSI參考模型物理層三、其它的層次結(jié)構(gòu)目前在大型商業(yè)應(yīng)用軟件系統(tǒng)中還流行一種包含中間件(Middleware)的層次結(jié)構(gòu),如圖所示[Jacobson1997]。中間件支持與平臺無關(guān)的分布式計(jì)算,可以用DCOM和CORBA對象來實(shí)現(xiàn)。MiddlewareBusiness-specificComponentsApplicationSystemsMiddlewareBusiness-specificComponentsApplicationSystemsSystemSoftwareSystemSoftware圖包含中間件的層次結(jié)構(gòu)客戶機(jī)/服務(wù)器結(jié)構(gòu)讓我們先回顧一下早期的電話系統(tǒng)。貝爾(AlexanderGrahamBell)于1876年申請了電話專利。那時(shí)期的電話必須一對一對地賣,用戶自己在兩個(gè)電話之間拉一根線。如果一個(gè)電話用戶想和其它幾個(gè)電話用戶通話,他必須拉n根單獨(dú)的線到每個(gè)人的房子里。于是在很短的時(shí)間內(nèi),城市里到處都是穿過房屋和樹木的混亂的電話線。很明顯,企圖把所有的電話完全互聯(lián)(如圖(a)所示)是行不通的。貝爾電話公司在1878年開辦了第一個(gè)交換局。公司為每個(gè)客戶架設(shè)一條線。打電話時(shí),客戶搖動(dòng)電話的曲柄使電話公司辦公室的鈴響起來,操作員聽到鈴聲以后根據(jù)要求將呼叫方和被呼叫方用跳線手工連接起來。這種集中交換式的模型如圖(b)所示。很快地,貝爾系統(tǒng)的交換局就出現(xiàn)在各地。人們又要求能打城市間的長途電話,就出現(xiàn)了二級交換局,以后進(jìn)一步發(fā)展為多個(gè)二級交換局。[Tanenbaum1998]交換局交換局(a)完全互聯(lián)的電話系統(tǒng)(b)集中交換式的電話系統(tǒng)如果將圖(b)中的電話看成是客戶程序,將中心的交換局看成是服務(wù)程序,那么圖(b)就是典型的客戶機(jī)/服務(wù)器結(jié)構(gòu)。注意這里客戶機(jī)和服務(wù)器都是指軟件而不是指硬件(一臺計(jì)算機(jī)可以放多個(gè)客戶機(jī)和服務(wù)器軟件)。客戶機(jī)/服務(wù)器結(jié)構(gòu)存在兩個(gè)顯然的優(yōu)點(diǎn):(1)以集中的方式高效率地管理通訊。前面講電話系統(tǒng)的故事就是要說明這一點(diǎn)。(2)可以共享資源。比如在信息管理系統(tǒng)中,服務(wù)器將信息集中起來,任何客戶機(jī)都可以通過訪問服務(wù)器而獲得所需的信息。客戶機(jī)和服務(wù)器之間的通訊以“請求——響應(yīng)”的方式進(jìn)行。客戶機(jī)先向服務(wù)器發(fā)起“請求”(Request),服務(wù)器再響應(yīng)(Response)這個(gè)請求,如圖所示。請求客戶機(jī)服務(wù)器客戶機(jī)服務(wù)器響應(yīng)圖Client和Server之間的通訊以“請求——響應(yīng)”的方式進(jìn)行采用“請求——響應(yīng)”這種通訊方式的基本動(dòng)機(jī)是為了解決“聚集”(Rendezvous)問題。為了理解這一個(gè)問題,設(shè)想一個(gè)人試圖在分離的機(jī)器上啟動(dòng)兩個(gè)程序并讓它們進(jìn)行通訊。還需記住,計(jì)算機(jī)的運(yùn)行速度要比人的操作速度高出許多數(shù)量級。在他啟動(dòng)第一個(gè)程序后,該程序開始執(zhí)行并向?qū)Φ瘸绦虬l(fā)送消息。在幾個(gè)微秒內(nèi),它便發(fā)現(xiàn)對等程序還不存在,于是就發(fā)出一條錯(cuò)誤消息,然后退出。此后,他啟動(dòng)了第二個(gè)程序。不幸的是,當(dāng)?shù)诙€(gè)程序開始執(zhí)行時(shí),它也找不到第一個(gè)程序(早已退出)。即使這兩個(gè)程序連續(xù)地重新試著通訊,但由于它們的執(zhí)行速度那么高,以致于它們在同一瞬間聯(lián)系上的概率非常低。在客戶機(jī)/服務(wù)器結(jié)構(gòu)中,服務(wù)器在啟動(dòng)后必須(無限期地)等待客戶機(jī)的“請求”,因此就形成了“請求——響應(yīng)”的通訊方式。在Internet/Intranet領(lǐng)域,目前“瀏覽器—Web服務(wù)器—數(shù)據(jù)庫服務(wù)器”結(jié)構(gòu)是一種非常流行的客戶機(jī)/服務(wù)器結(jié)構(gòu),如圖所示。這種結(jié)構(gòu)最大的優(yōu)點(diǎn)是:客戶機(jī)統(tǒng)一采用瀏覽器,這不僅讓用戶使用方便,而且使得客戶機(jī)端不存在維護(hù)的問題。當(dāng)然,軟件開發(fā)布和維護(hù)的工作不是自動(dòng)消失了,而是轉(zhuǎn)移到了Web服務(wù)器端。在Web服務(wù)器端,程序員要用腳本語言編寫響應(yīng)頁面。例如用Microsoft的ASP語言查詢數(shù)據(jù)庫服務(wù)器,將結(jié)果保存在Web頁面中,再由瀏覽器顯示出來??蛻魴C(jī)數(shù)據(jù)庫客戶機(jī)數(shù)據(jù)庫服務(wù)器Web服務(wù)器ASPEngine瀏覽器HTTP請求ASPEngine瀏覽器查詢HTTP響應(yīng)圖“瀏覽器—Web服務(wù)器—數(shù)據(jù)庫服務(wù)器”結(jié)構(gòu)模塊設(shè)計(jì)在設(shè)計(jì)好軟件的體系結(jié)構(gòu)后,就已經(jīng)在宏觀上明確了各個(gè)模塊應(yīng)具有什么功能,應(yīng)放在體系結(jié)構(gòu)的哪個(gè)位置。我們習(xí)慣地從功能上劃分模塊,保持“功能獨(dú)立”是模塊化設(shè)計(jì)的基本原則。因?yàn)?,“功能?dú)立”的模塊可以降低開發(fā)、測試、維護(hù)等階段的代價(jià)。但是“功能獨(dú)立”并不意味著模塊之間保持絕對的孤立。一個(gè)系統(tǒng)要完成某項(xiàng)任務(wù),需要各個(gè)模塊相互配合才能實(shí)現(xiàn),此時(shí)模塊之間就要進(jìn)行信息交流。比如手和腳是兩個(gè)“功能獨(dú)立”的模塊。沒有腳時(shí),手照樣能干活。沒有手時(shí),腳仍可以走路。但如果希望跑得快,那么邁左腳時(shí)一定要伸右臂甩左臂,邁右腳時(shí)則要伸左臂甩右臂。在設(shè)計(jì)一個(gè)模塊時(shí)不僅要考慮“這個(gè)模塊就該提供什么樣的功能”,還要考慮“這個(gè)模塊應(yīng)該怎樣與其它模塊交流信息”。本節(jié)將論述評價(jià)模塊設(shè)計(jì)優(yōu)劣的三個(gè)特征因素:“信息隱藏”、“內(nèi)聚與耦合”和“封閉——開放性”。信息隱藏在一節(jié)不和諧的課堂里,老師嘆氣道:“要是坐在后排聊天的同學(xué)能象中間打牌的同學(xué)那么安靜,就不會影響到前排睡覺的同學(xué)?!边@個(gè)故事告訴我們,如果不想讓壞事傳播開來,就應(yīng)該把壞事隱藏起來,“家丑不可外揚(yáng)”就是這個(gè)道理。為了盡量避免某個(gè)模塊的行為去干擾同一系統(tǒng)中的其它模塊,在設(shè)計(jì)模塊時(shí)就要注意信息隱藏。應(yīng)該讓模塊僅僅公開必須要讓外界知道的內(nèi)容,而隱藏其它一切內(nèi)容。模塊的信息隱藏可以通過接口設(shè)計(jì)來實(shí)現(xiàn)。一個(gè)模塊僅提供有限個(gè)接口(Interface),執(zhí)行模塊的功能或與模塊交流信息必須且只須通過調(diào)用公有接口來實(shí)現(xiàn)。如果模塊是一個(gè)C++對象,那么該模塊的公有接口就對應(yīng)于對象的公有函數(shù)。如果模塊是一個(gè)COM對象,那么該模塊的公有接口就是COM對象的接口。一個(gè)COM對象可以有多個(gè)接口,而每個(gè)接口實(shí)質(zhì)上是一些函數(shù)的集合。[Rogerson1999]美國也許是世界上丑聞最多的國家,因?yàn)樗非竺裰?,不懂得“隱藏信息”。但美國又是軟件產(chǎn)業(yè)最發(fā)達(dá)的國家,模塊化設(shè)計(jì)的方法都是美國人倡導(dǎo)的,他們應(yīng)該很懂得“隱藏信息”。真是前后矛盾,這些美國佬!內(nèi)聚與耦合內(nèi)聚(Cohesion)是一個(gè)模塊內(nèi)部各成分之間相關(guān)聯(lián)程度的度量。耦合(Coupling)是模塊之間依賴程度的度量。內(nèi)聚和耦合是密切相關(guān)的,與其它模塊存在強(qiáng)耦合的模塊通常意味著弱內(nèi)聚,而強(qiáng)內(nèi)聚的模塊通常意味著與其它模塊之間存在弱耦合。模塊設(shè)計(jì)追求強(qiáng)內(nèi)聚,弱耦合。一、內(nèi)聚強(qiáng)度內(nèi)聚按強(qiáng)度從低到高有以下幾種類型:(1)偶然內(nèi)聚。如果一個(gè)模塊的各成分之間毫無關(guān)系,則稱為偶然內(nèi)聚。(2)邏輯內(nèi)聚。幾個(gè)邏輯上相關(guān)的功能被放在同一模塊中,則稱為邏輯內(nèi)聚。如一個(gè)模塊讀取各種不同類型外設(shè)的輸入。盡管邏輯內(nèi)聚比偶然內(nèi)聚合理一些,但邏輯內(nèi)聚的模塊各成分在功能上并無關(guān)系,即使局部功能的修改有時(shí)也會影響全局,因此這類模塊的修改也比較困難。(3)時(shí)間內(nèi)聚。如果一個(gè)模塊完成的功能必須在同一時(shí)間內(nèi)執(zhí)行(如系統(tǒng)初始化),但這些功能只是因?yàn)闀r(shí)間因素關(guān)聯(lián)在一起,則稱為時(shí)間內(nèi)聚。(4)過程內(nèi)聚。如果一個(gè)模塊內(nèi)部的處理成分是相關(guān)的,而且這些處理必須以特定的次序執(zhí)行,則稱為過程內(nèi)聚。(5)通信內(nèi)聚。如果一個(gè)模塊的所有成分都操作同一數(shù)據(jù)集或生成同一數(shù)據(jù)集,則稱為通信內(nèi)聚。(6)順序內(nèi)聚。如果一個(gè)模塊的各個(gè)成分和同一個(gè)功能密切相關(guān),而且一個(gè)成分的輸出作為另一個(gè)成分的輸入,則稱為順序內(nèi)聚。(7)功能內(nèi)聚。模塊的所有成分對于完成單一的功能都是必須的,則稱為功能內(nèi)聚。二、耦合強(qiáng)度耦合的強(qiáng)度依賴于以下幾個(gè)因素:(1)一個(gè)模塊對另一個(gè)模塊的調(diào)用;(2)一個(gè)模塊向另一個(gè)模塊傳遞的數(shù)據(jù)量;(3)一個(gè)模塊施加到另一個(gè)模塊的控制的多少;(4)模塊之間接口的復(fù)雜程度。耦合按從強(qiáng)到弱的順序可分為以下幾種類型:(1)內(nèi)容耦合。當(dāng)一個(gè)模塊直接修改或操作另一個(gè)模塊的數(shù)據(jù),或者直接轉(zhuǎn)入另一個(gè)模塊時(shí),就發(fā)生了內(nèi)容耦合。此時(shí),被修改的模塊完全依賴于修改它的模塊。(2)公共耦合。兩個(gè)以上的模塊共同引用一個(gè)全局?jǐn)?shù)據(jù)項(xiàng)就稱為公共耦合。(3)控制耦合。一個(gè)模塊在界面上傳遞一個(gè)信號(如開關(guān)值、標(biāo)志量等)控制另一個(gè)模塊,接收信號的模塊的動(dòng)作根據(jù)信號值進(jìn)行調(diào)整,稱為控制耦合。(4)標(biāo)記耦合。模塊間通過參數(shù)傳遞復(fù)雜的內(nèi)部數(shù)據(jù)結(jié)構(gòu),稱為標(biāo)記耦合。此數(shù)據(jù)結(jié)構(gòu)的變化將使相關(guān)的模塊發(fā)生變化。(5)數(shù)據(jù)耦合。模塊間通過參數(shù)傳遞基本類型的數(shù)據(jù),稱為數(shù)據(jù)耦合。(6)非直接耦合。模塊間沒有信息傳遞時(shí),屬于非直接耦合。如果模塊間必須存在耦合,就盡量使用數(shù)據(jù)耦合,少用控制耦合,限制公共耦合的范圍,堅(jiān)決避免使用內(nèi)容耦合。封閉——開放性如果一個(gè)模塊可以作為一個(gè)獨(dú)立體被其它程序引用,則稱模塊具有封閉性。如果一個(gè)模塊可以被擴(kuò)充,則稱模塊具有開放性。從字面上看,讓模塊具有“封閉——開放性”是矛盾的,但這種特征在軟件開發(fā)過程中是客觀存在的。當(dāng)著手一個(gè)新問題時(shí),我們很難一次性解決問題。應(yīng)該先縱觀問題的一些重要方面,同時(shí)作好以后補(bǔ)充的準(zhǔn)備。因此讓模塊存在“開放性”并不是壞事情?!胺忾]性”也是需要的,因?yàn)槲覀儾荒艿鹊酵耆莆战鉀Q問題的信息后再把程序做成別人能用的模塊。模塊的“封閉——開放性”實(shí)際上對應(yīng)于軟件質(zhì)量因素中的可復(fù)用性和可擴(kuò)充性。采用面向過程的方法進(jìn)行程序設(shè)計(jì),很難開發(fā)出既具有封閉性又具有開放性的模塊。采用面向?qū)ο笤O(shè)計(jì)方法可以較好地解決這個(gè)問題。數(shù)據(jù)結(jié)構(gòu)與算法設(shè)計(jì)學(xué)會設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)與算法,可以讓我們編寫出高效率的程序。也許有人要問,在計(jì)算機(jī)速度日新月異的今天,為什么還需要高效率的程序因?yàn)槲覀兊男坌呐c能力是一起增長的,技術(shù)進(jìn)步最快也快不過人們欲望的增長。計(jì)算速度和存儲容量上的革新僅僅提供了處理更復(fù)雜問題的有效工具,所以高效率的程序永遠(yuǎn)不會過時(shí)。設(shè)計(jì)高效率的程序是基于良好的數(shù)據(jù)結(jié)構(gòu)與算法,而不是基于編程小技巧。大多數(shù)計(jì)算機(jī)科學(xué)系在設(shè)置課程時(shí),都重視學(xué)習(xí)基本的軟件工程原理,以及數(shù)據(jù)結(jié)構(gòu)與算法設(shè)計(jì)。一般說來,數(shù)據(jù)結(jié)構(gòu)與算法就是一類數(shù)據(jù)的表示及其相關(guān)的操作(這里算法不是指數(shù)值計(jì)算的算法)。從數(shù)據(jù)表示的觀點(diǎn)來看,存儲在數(shù)組中的一個(gè)有序整數(shù)表也是一種數(shù)據(jù)結(jié)構(gòu)。算法是指對數(shù)據(jù)結(jié)構(gòu)施加的一些操作,例如對一個(gè)線性表進(jìn)行檢索、插入、刪除等操作。一個(gè)算法如果能在所要求的資源限制(ResourceConstraints)范圍內(nèi)將問題解決好,則稱這個(gè)算法是有效率(Efficient)的。例如一個(gè)資源限制可能是“用于存儲數(shù)據(jù)的內(nèi)存有限”,或者“允許執(zhí)行每個(gè)子任務(wù)所需的時(shí)間有限”。一個(gè)算法如果比其它已知算法所需要的資源都少,這個(gè)算法也被稱為是有效率的。算法的代價(jià)(Cost)是指消耗的資源量。一般說來,代價(jià)是由一個(gè)關(guān)鍵資源例如時(shí)間或空間來評估的。毋庸置疑,人們編寫程序是為了解決問題。只有通過預(yù)先分析問題來確定必須達(dá)到的性能目標(biāo),才有希望挑選出正確的數(shù)據(jù)結(jié)構(gòu)。有相當(dāng)多的程序員忽視了這一分析過程,而直接選用某一個(gè)他們習(xí)慣使用的,但是與問題不相稱的數(shù)據(jù)結(jié)構(gòu),結(jié)果設(shè)計(jì)出一個(gè)低效率的程序。如果使用簡單的設(shè)計(jì)就能夠達(dá)到性能目標(biāo)時(shí),選用復(fù)雜的數(shù)據(jù)結(jié)構(gòu)也是沒有道理的。人們對常用的數(shù)據(jù)結(jié)構(gòu)與算法的研究已經(jīng)相當(dāng)透徹,可以歸納出一些設(shè)計(jì)原則:(1)每一種數(shù)據(jù)結(jié)構(gòu)與算法都有其時(shí)間、空間的開銷和收益。當(dāng)面臨一個(gè)新的設(shè)計(jì)問題時(shí),設(shè)計(jì)者要徹底地掌握怎樣權(quán)衡時(shí)空開銷和算法有效性的方法。這就需要懂得算法分析的原理,而且還需要了解所使用的物理介質(zhì)的特性(例如,數(shù)據(jù)存儲在磁盤上與存儲在內(nèi)存中,就有不同的考慮)。(2)與開銷和收益有關(guān)的是時(shí)間——空間的權(quán)衡。通常可以用更大的時(shí)間開銷來換取空間的收益,反之亦然。時(shí)間——空間的權(quán)衡普遍地存在于軟件開發(fā)的各個(gè)階段中。(3)程序員應(yīng)該充分地了解一些常用的數(shù)據(jù)結(jié)構(gòu)與算法,避免不必要的重復(fù)設(shè)計(jì)工作。(4)數(shù)據(jù)結(jié)構(gòu)與算法為應(yīng)用服務(wù)。我們必須先了解應(yīng)用的需求,再尋找或設(shè)計(jì)與實(shí)際應(yīng)用相匹配的數(shù)據(jù)結(jié)構(gòu)。[Shaffer1998]用戶界面設(shè)計(jì)某個(gè)人總有辦法讓自己保持心情愉快、信心十足。有一天,他向一名圍棋九段和一名乒乓球世界冠軍挑戰(zhàn),結(jié)果他全勝了。因?yàn)樗鷩寰哦未蚱古仪?,跟乒乓球冠軍下圍棋。用戶界面的編程技術(shù)是人們熟悉得不得了的事,我決定講一講比較陌生的“用戶界面設(shè)計(jì)美學(xué)”。有位愛好書畫的博士后請我欣賞鋼琴演奏會。我從頭到尾只聽到“叮叮咚咚”的聲音,實(shí)在享受不到“高雅”,就請這位朋友指點(diǎn)。他雖然也不懂鋼琴,卻從欣賞書法的角度設(shè)法解釋如何欣賞音樂。可是我既不懂書法也不懂音樂,真是坐立不安?!懊馈彼坪跽娴牟豢裳詡鳌N以谧x本科時(shí),特別喜歡編寫用戶界面程序,并且常向同學(xué)演示、賣弄。我覺得還不過癮,就寫了一篇“用戶界面設(shè)計(jì)美學(xué)”的短文[林銳1997]。凡是路過我實(shí)驗(yàn)室的同學(xué)都被我逮住,被迫聽完我得意之極的朗讀,茫然者與痛苦者居多。不久我的朗讀便所向披糜,聞聲者逃之夭夭。現(xiàn)在我又把那篇短文摘錄至此,請您忍著點(diǎn)吧。界面設(shè)計(jì)中美的需求與導(dǎo)向作用人們對美的向往和追求是與生俱有的。顯然沒有人愿意丑化自己的程序,也沒有用戶嗜好丑陋的界面。軟件開發(fā)者要設(shè)計(jì)美,用戶要享受美,所以界面的美是開發(fā)者與用戶的共同需求。界面美的概念很抽象,以致讓人無法說清楚什么是界面的美。但它同時(shí)又很現(xiàn)實(shí),以致人人都可以去欣賞和感受界面美,并且挑剔美中之不足。美學(xué)不是一種量化的學(xué)問,如果因此而輕視美學(xué)指導(dǎo),必將導(dǎo)致在設(shè)計(jì)過程中光依賴程序員個(gè)人的經(jīng)驗(yàn)與感覺。由于程序員接受的教育主要是如何使計(jì)算機(jī)完成工作,而不是人如何工作,因此僅靠程序員主觀想象設(shè)計(jì)而成的界面往往得不到大眾用戶的認(rèn)可。美的界面能消除用戶由感覺引起的乏味、緊張和疲勞(情緒低落),大大提高用戶的工作效率,從而進(jìn)一步為發(fā)揮用戶技能和為用戶完成任務(wù)作出貢獻(xiàn)。從人機(jī)界面發(fā)展歷史與趨勢上可以看出人們對界面美的需求,以及美在界面設(shè)計(jì)中的導(dǎo)向作用。界面設(shè)計(jì)已經(jīng)經(jīng)歷了兩個(gè)界限分明的時(shí)代。第一代是以文本為基礎(chǔ)的簡單交互,如常見的命令行,字符菜單等。由于第一代界面考慮人的因素太少,用戶興趣不高。隨著技術(shù)的發(fā)展,出現(xiàn)了第二代直接操縱的界面。它大量使用圖形、語音和其它交互媒介,充分地考慮了人對美的需求。直接操縱的界面使用視聽、觸摸等技術(shù),讓人可以憑借生活常識、經(jīng)歷和推理來操縱軟件,愉快地完成任務(wù)。更高層次的界面甚至模擬了人的生活空間,例如虛擬現(xiàn)實(shí)環(huán)境。界面的美充分體現(xiàn)了人機(jī)交互作用中人的特性與意圖,越來越多的用戶將通過具有吸引力而令人愉快的人機(jī)界面與計(jì)算機(jī)打交道。界面美的內(nèi)涵本節(jié)從合適性、風(fēng)格和廣義美三個(gè)方面論述界面美的內(nèi)涵。一、界面的合適性界面的合適性是指界面是否與軟件功能相融洽。如果界面不適合于軟件的功能,那么界面將毫無用處,界面美的內(nèi)涵就無從談起。所以界面的合適性是界面美的首要因素,它提醒設(shè)計(jì)者不要片面追求外觀漂亮而導(dǎo)致失真或華而不實(shí)。界面的合適性既提倡外美內(nèi)秀,又強(qiáng)調(diào)恰如其分。合適性差的界面無疑會混淆軟件意圖,致使用戶產(chǎn)生誤解。即使它不損害軟件功能與性能,也會使用戶產(chǎn)生不該有的情緒波動(dòng)。例如一些軟件開發(fā)者喜歡為其作品加一段動(dòng)畫演示,以便吸引更多用戶的關(guān)注。這本是無可非議的,問題在于這演示是否合情合理。如果運(yùn)行一個(gè)程序,它首先表演一套復(fù)雜的動(dòng)畫,在后臺演奏雄壯的進(jìn)行曲,電閃雷鳴之后出來的卻是一個(gè)普通的文本編輯器。整個(gè)過程讓用戶置身于云里霧里,而結(jié)果卻讓用戶感到驚諤而不是驚喜。合適性差的界面只會給軟件帶來厄運(yùn)。二、界面的風(fēng)格界面的風(fēng)格有兩類,一是“一致性”,二是“個(gè)性化”。商業(yè)應(yīng)用軟件的界面設(shè)計(jì)注重一致性。設(shè)計(jì)者必須密切注意在相同應(yīng)用領(lǐng)域中最流行的軟件的界面,必須尊重用戶使用這些軟件的習(xí)慣。例如商業(yè)軟件習(xí)慣于設(shè)置F1鍵為幫助熱鍵,如果某個(gè)設(shè)計(jì)者別出心裁地讓F1鍵成為程序終止的熱鍵,那么在用戶渴望得到幫助而伸手擊F1鍵的一剎那,他的工作就此完蛋。相信這個(gè)用戶“一朝被蛇咬,十年怕井繩”。目前流行的軟件開發(fā)工具如VisualC++、VisualBasic、Delphi、C++Builder、PowerBuilder等,都能夠快速地開發(fā)出非常相似的圖形用戶界面。在Internet/Intranet領(lǐng)域,瀏覽器幾乎成了唯一的客戶機(jī)程序,因?yàn)橛脩粝M猛耆恢碌能浖硗瓿汕ё內(nèi)f化的應(yīng)用任務(wù)。在娛樂領(lǐng)域的軟件中,有個(gè)性化的界面自然比泯然于眾的界面更具有吸引力。一般說來,計(jì)算機(jī)專業(yè)人員玩過的軟件不計(jì)其數(shù)。界面看多了,真有種“曾經(jīng)滄海難為水”的感覺。不過當(dāng)我看到一個(gè)叫Sonique的放音樂的軟件時(shí),不禁對其界面的創(chuàng)意嘖嘖稱贊,忍不住象貼美女像那樣把它貼到書中,如圖所示。圖Sonique軟件的幾種界面人們經(jīng)常搞不清楚什么情況下應(yīng)該追求“一致性”或“個(gè)性化”。在大白天,當(dāng)人們都穿戴整齊時(shí),有些人喜歡只掛幾片遮羞布。而當(dāng)大家都赤條條地在共公浴室洗澡時(shí),卻也有人喜歡穿著衣服。三、界面的廣義美盡管界面的美并沒有增加軟件的功能與性能,卻又是必為可少的。用戶使用界面時(shí),除了直接的感官美感外,還有很大一部分美感是間接的,它們存在于人們的使用體驗(yàn)中,例如方便,實(shí)用等。與圖形用戶界面相比,命令行是最原始的界面,它難記又難看。但對于熟練的用戶而言,他們樂于使用命令行以獲得高效率。命令行因具有高效率而贏得了專業(yè)人士的喜愛,早期的Unix系統(tǒng)就是徹頭徹尾的命令系統(tǒng)。可以說,一切有利于人機(jī)交互的界面設(shè)計(jì)因素都具有廣義美。界面設(shè)計(jì)的一些特殊考慮也體現(xiàn)了廣義美,如設(shè)法使殘障人也可以使用軟件。IBM公司在1985年已經(jīng)創(chuàng)建了殘障人國家支持中心。Apple公司的專門教育辦公室則提供了一些有利于殘障人使用的計(jì)算機(jī)信息產(chǎn)品。系統(tǒng)設(shè)計(jì)示例——支持協(xié)同工作的交互式三維圖形軟件開發(fā)系統(tǒng)本節(jié)論述“支持協(xié)同工作的交互式三維圖形軟件開發(fā)系統(tǒng)”的系統(tǒng)設(shè)計(jì),作為本章的示例(取材于作者的博士論文工作[林銳2000])。設(shè)計(jì)背景圖形標(biāo)準(zhǔn)在圖形領(lǐng)域有著重要的地位,它不僅加速了3D應(yīng)用程序的開發(fā),而且使3D應(yīng)用程序的可移植性更好。歷史上曾出現(xiàn)的圖形標(biāo)準(zhǔn)(或API)有Core、GKS、PHIGS、PEX、GL、Dore、RenderMan、Hoops、OpenGL等等。經(jīng)過競爭與淘汰,目前OpenGL成為國際上公認(rèn)的3D圖形工業(yè)標(biāo)準(zhǔn),在Unix與PC平臺得到廣泛應(yīng)用。OpenGL提供了數(shù)百個(gè)庫函數(shù),可以方便地繪制具有真實(shí)感的3D圖形。但是在開發(fā)交互式的3D圖形應(yīng)用程序時(shí),圖形的繪制只是一部分工作,更多的工作集中在場景數(shù)據(jù)結(jié)構(gòu)、圖形對象、三維交互和圖形用戶界面的設(shè)計(jì)上。由于OpenGL與窗口系統(tǒng)無關(guān),不提供任何交互手段,必須由程序員自己編寫所有的交互功能。并且OpenGL的編程接口是低級的C函數(shù),不提供可復(fù)用的對象庫或者應(yīng)用程序框架,開發(fā)效率不高。為了克服這些困難,人們往往在圖形標(biāo)準(zhǔn)之上再建立更高級的開發(fā)工具(3DToolkit或3DEngine)?;贠penGL的著名的開發(fā)工具有OpenInventor、IRISPerformer、Optimeizer/Cosmo3D以及GLUT等等。OpenInventor被譽(yù)為是交互式3D開發(fā)工具的“事實(shí)標(biāo)準(zhǔn)”,但顯然沒有一個(gè)3D開發(fā)工具能滿足所有的應(yīng)用需求,3D的廣泛應(yīng)用需要更多的開發(fā)工具支持。 隨著計(jì)算機(jī)圖形技術(shù)與網(wǎng)絡(luò)技術(shù)的迅猛發(fā)展,兩者的結(jié)合勢在必行。在商業(yè)、科研、教育、娛樂等領(lǐng)域,用于分布式虛擬環(huán)境(DistributedVirtualEnvironments,DVEs)和計(jì)算機(jī)支持協(xié)同工作(ComputerSupportedCooperativeWork,CSCW)的圖形系統(tǒng)已成為研究與應(yīng)用的熱點(diǎn)。著名的DVEs系統(tǒng)有DIVE、dVS、MR、Repo-3D等。但是這些DVEs系統(tǒng)缺乏3D開發(fā)工具的交互式圖形功能以及通用性,而通用的3D開發(fā)工具如OpenInventor則又不支持分布式計(jì)算和協(xié)同工作。由于在窗口系統(tǒng)、圖形支撐庫、編程語言等方面存在差異,上述DVEs系統(tǒng)和3D開發(fā)工具難以方便地結(jié)合使用。我們多方面分析了3D需求及軟硬件條件,研制完成運(yùn)行于PC平臺,支持協(xié)同工作的交互式三維圖形軟件開發(fā)系統(tǒng),如圖所示。其中:(1)Intra3D是基于OpenGL的通用交互式三維圖形軟件開發(fā)工具,可用于快速開發(fā)Window9x/NT下的交互式三維圖形應(yīng)用軟件。(2)CNC是支持協(xié)同工作的網(wǎng)絡(luò)通訊開發(fā)系統(tǒng)(CooperativeNetworkCommunicator),其核心是支持“發(fā)布—訂閱模式”與“組播模式”的服務(wù)器與API。結(jié)合Intra3D和CNC,可以快速開發(fā)支持協(xié)同工作的交互式三維圖形應(yīng)用軟件。支持協(xié)同工作的網(wǎng)絡(luò)通訊開發(fā)系統(tǒng)CNC通用交互式三維圖形軟件開發(fā)工具支持協(xié)同工作的網(wǎng)絡(luò)通訊開發(fā)系統(tǒng)CNC通用交互式三維圖形軟件開發(fā)工具Intra3D圖支持協(xié)同工作的交互式三維圖形軟件開發(fā)系統(tǒng)通用交互式三維圖形軟件開發(fā)工具Intra3DIntra3D的核心是集成了場景數(shù)據(jù)結(jié)構(gòu)、圖形對象、三維交互算法和圖形用戶界面的C++類庫與COM(ComponentObjectModel)對象庫,支持VisualC++、VisualBasic、Delphi等語言的應(yīng)用編程。Intra3D的核心庫分四層創(chuàng)建:(1)第一層為“基礎(chǔ)對象與函數(shù)”(BasicObjectsandFunctions);(2)第二層為“圖形對象”(GraphicalObjects);(3)第三層為“場景圖與節(jié)點(diǎn)”(SceneGraphandNodes);(4)第四層為“繪制與交互”(RenderingandInteraction)。體系結(jié)構(gòu)如圖所示,其中高層構(gòu)件可以引用低層構(gòu)件,但低層構(gòu)件不能引用高層構(gòu)件。4、繪制與交互層1、基礎(chǔ)對象與函數(shù)層3、場景的圖與節(jié)點(diǎn)層2、圖形對象層Intra3D4、繪制與交互層1、基礎(chǔ)對象與函數(shù)層3、場景的圖與節(jié)點(diǎn)層2、圖形對象層Intra3DC++類庫Intra3DCOM庫圖Intra3D的體系結(jié)構(gòu)Intra3D是免費(fèi)軟件,有配套書籍《交互式三維圖形技術(shù)與程序設(shè)計(jì)》。標(biāo)準(zhǔn)版軟件約25兆,核心庫7萬多行C++代碼全部公開,用戶可以方便地修改內(nèi)核以適應(yīng)不同的需求。主要模塊和功能一、基礎(chǔ)對象與函數(shù)層(1)定義了用于對象引用計(jì)數(shù)的內(nèi)存管理基類;(2)矢量、矩陣與四元組運(yùn)算,鼠標(biāo)跟蹤球算法;(3)點(diǎn)陣字體與三維矢量字體輸出,常用于數(shù)據(jù)可視化圖形的數(shù)據(jù)標(biāo)注;(4)圖像輸入輸出以及紋理映像,支持BMP、GIF、JPEG、SGI、TGA等圖像格式;(5)常用幾何圖元的繪制,如錐、柱、球、環(huán)等,并支持Swept形體,螺旋體的繪制;(6)提供450余種材質(zhì),在第四層中可以交互式編輯這些材質(zhì)。二、圖形對象層圖形對象能將數(shù)據(jù)轉(zhuǎn)化為幾何模型并可以繪制出來。Intra3D版提供了三類圖形對象:(1)常用幾何對象,如長方體、錐體、圓柱體、球體、圓環(huán)體、Swept形體等;(2)多邊形模型對象,可用于繪制Autodesk公司.3ds模型和Wavefront公司的.obj模型;(3)商業(yè)統(tǒng)計(jì)圖形對象,如柱形圖、帶狀圖、條形圖、折線圖、面積圖、餅圖、塔形圖、曲線圖、曲面圖、進(jìn)程圖、股票圖等。圖形對象的開發(fā)與應(yīng)用問題密切相關(guān),用戶可以使用繼承方法擴(kuò)充新的圖形對象,而不會影響到其它三層的構(gòu)件。三、場景圖與節(jié)點(diǎn)場景圖(SceneGraph)是有向無環(huán)圖,SceneGraph的主要節(jié)點(diǎn)有:(1)SceneNode是所有節(jié)點(diǎn)的基類。在SceneNode中定義了局部坐標(biāo)系以及相應(yīng)的圖形變換,這樣便于第四層以同樣的操作方式實(shí)現(xiàn)三維交互。(2)相機(jī)節(jié)點(diǎn)(CameraNode)支持平行投影與透視投影,支持多個(gè)相機(jī)切換。(3)光源節(jié)點(diǎn)有三種:平行光源節(jié)點(diǎn)(DirLightNode)、點(diǎn)光源節(jié)點(diǎn)(PointLightNode)和錐光源節(jié)點(diǎn)(SpotLightNode)。(4)形體節(jié)點(diǎn)(ShapeNode)用于引用圖形對象,有關(guān)圖形對象的三維交互均由ShapeNode處理。四、繪制與交互層Intra3D的交互分兩類:一類是對形體、光源和相機(jī)的直接操作,另一類是真實(shí)感屬性的編輯。Intra3D的場景視圖構(gòu)件(SceneView)封裝了交互式繪制的所有細(xì)節(jié),如消息處理、場景節(jié)點(diǎn)的遍歷繪制、多重采樣消鋸齒、鼠標(biāo)交互等。為了便于編輯真實(shí)感屬性,Intra3D定制了一些常用對話:矢量字體對話(FontDialog)、顏色對話(ColorDialog)、材質(zhì)庫對話(MaterialLibDialog)、材質(zhì)對話(MaterialDialog)與光源對話(DirLightDialog,PointLightDialog,SpotLightDialog)。用戶界面設(shè)計(jì)Intra3D的場景視圖構(gòu)件SceneView用于快速創(chuàng)建交互式3D應(yīng)用程序的主界面。SceneView支持selecting、scaling、rotating、translating
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 無抵押貸款合同樣式
- 員工離職協(xié)議模板
- 配電室維護(hù)協(xié)議書
- 權(quán)威加工合同范文合輯
- 大學(xué)新生入學(xué)法律協(xié)議范文
- 全面服裝代理合同范本
- 消防工程專業(yè)承包合同
- 廣告位承包協(xié)議范本
- 美術(shù)作品購買協(xié)議范本2024年
- 個(gè)人稅收居民證明委托申請
- 學(xué)校田徑運(yùn)動(dòng)會所需各表格(團(tuán)體總分記錄表-徑賽檢錄表-徑賽計(jì)時(shí)表-終點(diǎn)名次報(bào)告表-田賽遠(yuǎn)度表)等
- 2023年國開大學(xué)期末考復(fù)習(xí)題-02316-中級財(cái)務(wù)會計(jì)(一)
- 【護(hù)理學(xué)個(gè)案護(hù)理論文:一例潰瘍性結(jié)腸炎患者的護(hù)理5600字】
- 教育政策與法規(guī)全套完整教學(xué)課件
- GPS測量與數(shù)據(jù)處理完整整套教學(xué)課件
- 護(hù)士讀書分享《喚醒護(hù)理》
- 高標(biāo)準(zhǔn)農(nóng)田灌溉與排水工程施工方案
- 《觀察葉片的結(jié)構(gòu)》 說課課件
- 醫(yī)院透析患者安全管理應(yīng)急預(yù)案
- 《BIM技術(shù)的應(yīng)用研究開題報(bào)告(含提綱)》
- GB/T 40997-2021經(jīng)外奇穴名稱與定位
評論
0/150
提交評論