第3章 經(jīng)典軟件體系結(jié)構(gòu)風(fēng)格_第1頁
第3章 經(jīng)典軟件體系結(jié)構(gòu)風(fēng)格_第2頁
第3章 經(jīng)典軟件體系結(jié)構(gòu)風(fēng)格_第3頁
第3章 經(jīng)典軟件體系結(jié)構(gòu)風(fēng)格_第4頁
第3章 經(jīng)典軟件體系結(jié)構(gòu)風(fēng)格_第5頁
已閱讀5頁,還剩81頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第3章經(jīng)典軟件體系結(jié)構(gòu)風(fēng)格《軟件體系結(jié)構(gòu)與設(shè)計實用教程》第二版3.1調(diào)用-返回風(fēng)格3.1.1主程序-子程序風(fēng)格結(jié)構(gòu)化方法設(shè)計思路:自頂向下、逐步求精。采用模塊分解與功能抽象,自頂向下、分而治之程序結(jié)構(gòu):按功能劃分為若干個基本模塊,形成一個樹狀結(jié)構(gòu)各模塊間的關(guān)系盡可能簡單,功能上相對獨立;每一模塊內(nèi)部均是由順序、選擇和循環(huán)三種基本結(jié)構(gòu)組成其模塊化實現(xiàn)的具體方法是使用函數(shù)(子程序)主程序-子過程風(fēng)格的基本構(gòu)成組件主程序、子程序連接件調(diào)用-返回機(jī)制拓?fù)浣Y(jié)構(gòu)層次化結(jié)構(gòu)本質(zhì):將大系統(tǒng)分解為若干模塊(模塊化),主程序調(diào)用這些模塊實現(xiàn)完整的系統(tǒng)功能。voidmain(){printstar();printmessage();}例#include<stdio.h>voidprintstar(){printf(“*************\n”);}voidprintmessage(){printf(“Hello,world.\n”);printstar();}組件主程序main()子程序printstar()和printmessage()連接件主程序main()調(diào)用子程序printstar()和printmessage()因為沒有參數(shù)的傳遞,所以比較簡單。含有參數(shù)的子程序的一般調(diào)用過程如下。按從右到左的順序,計算實參各表達(dá)式的值;按照位置,將實參的值一一傳給形參;執(zhí)行被調(diào)用函數(shù)(子程序);當(dāng)遇到return(表達(dá)式)語句時,計算表達(dá)式的值,并返回主調(diào)函數(shù)(主程序)。函數(shù)參數(shù)和函數(shù)的值——調(diào)用返回機(jī)制例#include<stdio.h>intmax(intx,inty){intz;z=x>y?x:y;return(z);}voidmain(){inta,b,c;scanf(“%d,%d”,&a,&b);c=max(a,b);printf(“Themaxis%d”,);}組件主程序main()函數(shù)子程序max(a,b)函數(shù);連接件main()函數(shù)中調(diào)用max(a,b)函數(shù),max()函數(shù)將實參a、b分別傳遞給虛參x、y,通過運算得到較大值z,并將z返回調(diào)用處,賦值給main()函數(shù)的變量c。主程序-子過程風(fēng)格的優(yōu)點與缺點優(yōu)點:有效地將一個較復(fù)雜的程序系統(tǒng)設(shè)計任務(wù)分解成許多易于控制和處理的子任務(wù),便于開發(fā)和維護(hù)已被證明是成功的設(shè)計方法,可以被用于較大程序主程序-子過程風(fēng)格的優(yōu)點與缺點缺點:規(guī)模:程序超過10萬行,表現(xiàn)不好

;程序太大,開發(fā)太慢,測試越來越困難可重用性差、數(shù)據(jù)安全性差,難以開發(fā)大型軟件和圖形界面的應(yīng)用軟件把數(shù)據(jù)和處理數(shù)據(jù)的過程分離為相互獨立的實體,當(dāng)數(shù)據(jù)結(jié)構(gòu)改變時,所有相關(guān)的處理過程都要進(jìn)行相應(yīng)的修改圖形用戶界面的應(yīng)用程序,很難用過程來描述和實現(xiàn),開發(fā)和維護(hù)也都很困難。3.1.2面向?qū)ο箫L(fēng)格OO風(fēng)格基本構(gòu)成組件對象,或者說是抽象數(shù)據(jù)類型(類)的實例類連接件對象是通過函數(shù)和過程的調(diào)用-返回機(jī)制來交互的類通過定義對象,再采用調(diào)用調(diào)用-返回機(jī)制進(jìn)行交互classSpot{privateintx,y;Spot(intu,intv){setX(u);setY(v);}voidsetX(intx1){x=x1;}voidsetY(inty1){y=y1;}intgetX(){returnx;}intgetY(){returny;}}classTrans{voidmove(Spotp,inth,intk){p.setX(p.getX()+h);p.setY(p.getY()+k);}}classTest{publicstaticvoidmain(Stringargs[]){Spots=newSpot(2,3);System.out.println("s點的坐標(biāo):"+s.getX()+","+s.getY());Transts=newTrans();ts.move(s,4,5);System.out.println("s點的坐標(biāo):"+s.getX()+","+s.getY());}}組件Spot、Trans、Test三個類Spot的對象s,Trans的對象ts。連接件如下在Test類里面創(chuàng)建Spot類的對象s、Trans類的對象ts,Trans類的move()方法的參數(shù)里面有Spot類的對象p。Test類使用Spot類的對象s,調(diào)用了Spot類的getX()和getY()方法;Test類使用Trans類的對象ts,調(diào)用了Trans類move()方法,并把實參Spot類的對象s傳遞給了虛參Spot類的對象p。OO特性抽象封裝:限制對某些信息的訪問多態(tài):在運行時選擇具體的操作繼承:對共享的功能保持唯一的接口交互:通過過程調(diào)用或類似的協(xié)議動態(tài)綁定:運行時決定實際調(diào)用的操作復(fù)用和維護(hù)OO風(fēng)格優(yōu)點復(fù)用和維護(hù):利用封裝和聚合提高生產(chǎn)力因為對象對其它對象隱藏它的表示,所以可以改變一個對象的表示,而不影響其它的對象。某一組件的算法與數(shù)據(jù)結(jié)構(gòu)的修改不會影響其他組件組件之間依賴性降低,提高了復(fù)用度反映現(xiàn)實世界容易分解一個系統(tǒng)設(shè)計者可將一些數(shù)據(jù)存取操作的問題分解成一些交互的代理程序的集合OO風(fēng)格缺點管理大量的對象:怎樣確立大量對象的結(jié)構(gòu)繼承引起復(fù)雜度,關(guān)鍵系統(tǒng)中慎用必須知道對象的身份為了使一個對象和另一個對象通過過程調(diào)用等進(jìn)行交互,必須知道對象的標(biāo)識。只要一個對象的標(biāo)識改變了,就必須修改所有其他明確顯式調(diào)用它的對象,并消除由此帶來的一些副作用(例如,如果A使用了對象B,C也使用了對象B,那么,C對B的使用所造成的對A的影響可能是料想不到的)對比:在管道-過濾器系統(tǒng)中,一個過濾器無需知道其他過濾器的任何信息不是特別適合功能的擴(kuò)展。為了增加新功能,要么修改已有的模塊,要么就加入新的模塊,從而影響性能3.2數(shù)據(jù)流風(fēng)格3.2.1數(shù)據(jù)流體系結(jié)構(gòu)風(fēng)格的基本特征數(shù)據(jù)流風(fēng)格由數(shù)據(jù)控制計算系統(tǒng)結(jié)構(gòu)由數(shù)據(jù)在處理之間的有序移動決定數(shù)據(jù)流系統(tǒng)的結(jié)構(gòu)是顯而易見的在純數(shù)據(jù)流系統(tǒng)中,處理之間除了數(shù)據(jù)交換,沒有任何其他的交互一個直觀實例:在MSExcel中,改變某個單元格的值,則依賴于該單元格的其他單元格的值也會隨之改變。三種典型的數(shù)據(jù)流風(fēng)格批處理管道-過濾器過程控制,3.73.2.1批處理風(fēng)格每個處理步驟是一個獨立的程序每一步必須在前一步結(jié)束后才能開始數(shù)據(jù)必須是完整的,以整體的方式傳遞典型應(yīng)用:傳統(tǒng)的數(shù)據(jù)處理程序編譯/CASE(computeraidedsoftwareengineering)工具

批處理風(fēng)格-基本構(gòu)成基本組件獨立的應(yīng)用程序連接件某種類型的媒質(zhì)(magnetic

tape)表達(dá)拓?fù)浣Y(jié)構(gòu)連接件定義了相應(yīng)的數(shù)據(jù)流圖每一步驟必須在前一步驟完全結(jié)束之后方能開始程序1將一批數(shù)據(jù)以二進(jìn)制形式存放在磁盤文件中。#include<fstream>usingnamespacestd;structstudent{charname[20];intnum;intage;charsex;};intmain(){studentstud[3]={"Li",1001,18,'f',"Fun",1002,19,'m',"Wang",1004,17,'f'};ofstreamoutfile("stud.dat",ios::binary);if(!outfile){cerr<<"openerror!"<<endl;abort();//退出程序

}for(inti=0;i<3;i++)outfile.write((char*)&stud[i],sizeof(stud[i]));outfile.close();return0;}程序2將剛才以二進(jìn)制形式存放在磁盤文件中的數(shù)據(jù)讀入內(nèi)存并在顯示器上顯示。#include<fstream>usingnamespacestd;structstudent{stringname;intnum;intage;charsex;};intmain(){studentstud[3];inti;ifstreaminfile("stud.dat",ios::binary);if(!infile){cerr<<"openerror!"<<endl;abort();}for(i=0;i<3;i++)infile.read((char*)&stud[i],sizeof(stud[i]));infile.close();for(i=0;i<3;i++){cout<<"NO."<<i+1<<endl;cout<<"name:"<<stud[i].name<<endl;cout<<"num:"<<stud[i].num<<endl;;cout<<"age:"<<stud[i].age<<endl;cout<<"sex:"<<stud[i].sex<<endl<<endl;}return0;}組件程序1程序2連接件文件stud.dat第一個java文件importjava.io.BufferedInputStream;importjava.io.DataInputStream;importjava.io.FileNotFoundException;importjava.io.FileInputStream;importjava.io.IOException;publicclassreceiver{FiletempFile=newFile("Data.dat");if(tempFile.exists()){System.out.println("文件Data.dat已經(jīng)存在!");System.exit(0);}publicvoidgetNumber(){DataInputStreamin=null;try{in=newDataInputStream(newBufferedInputStream(newFileInputStream(tempFile)));}catch(FileNotFoundExceptione){e.printStackTrace();}for(inti=0;i<6;i++)try{ System.out.print(""+in.readInt());}catch(IOExceptione){e.printStackTrace();}if(in!=null){try{ in.close();}catch(IOExceptione){e.printStackTrace();}}} }第二個java文件importjava.io.BufferedOutputStream;importjava.io.DataOutputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;publicclasssender{FiletempFile=newFile("Data.dat");if(tempFile.exists()){System.out.println("文件Data.dat已經(jīng)存在!");System.exit(0);}publicvoidoutNumber(){DataOutputStreamout=null;try{out=newDataOutputStream(newBufferedOutputStream(newFileOutputStream(tempFile)));}catch(FileNotFoundExceptione){e.printStackTrace();}for(inti=0;i<6;i++)try{out.writeInt((int)(Math.random()*100));}catch(IOExceptione){e.printStackTrace();}if(out!=null) {try{out.close();}catch(IOExceptione){e.printStackTrace();}}} }組件receiver程序sender程序;連接件文件Data.datsender程序,使用File類判斷當(dāng)前目錄中是否已存在文件Data.dat,如存在,則中斷程序的運行,否則繼續(xù);然后使用DataOutputStream及相關(guān)IO流類將隨機(jī)產(chǎn)生的6個整數(shù)存入數(shù)據(jù)文件Data.dat;receiver程序,使用DataInputStream及相關(guān)IO流類從Data.dat文件中讀取數(shù)據(jù),并在屏幕上顯示出來。3.2.2管道與過濾器風(fēng)格管道過濾器風(fēng)格的基本構(gòu)成(1)組件:過濾器,處理數(shù)據(jù)流一個過濾器封裝了一個處理步驟數(shù)據(jù)源點和數(shù)據(jù)終止點可以看作是特殊的過濾器過濾器對輸入流進(jìn)行處理、轉(zhuǎn)換,處理后的結(jié)果在輸出端流出。每個組件都有輸入/輸出集合,組件在輸入處讀取數(shù)據(jù)流,經(jīng)過內(nèi)部處理,在輸出處生成數(shù)據(jù)流。管道過濾器風(fēng)格的基本構(gòu)成(2)連接件:管道,連接一個源和一個目的過濾器轉(zhuǎn)發(fā)數(shù)據(jù)流數(shù)據(jù)可能是ASCII字符形成的流連接件位于過濾器之間,起到信息流的導(dǎo)管的作用,被稱為管道。連接件就象是數(shù)據(jù)流傳輸?shù)墓艿?,將一個過濾器的輸出傳到另一過濾器的輸入。管道只是對數(shù)據(jù)傳輸?shù)某橄?,它可能是管道,也可能是其它通信方式,甚至什么都沒有(所有過濾器都在原始數(shù)據(jù)基礎(chǔ)上進(jìn)行處理)

管道過濾器風(fēng)格的基本構(gòu)成(3)拓?fù)浣Y(jié)構(gòu):連接器定義了數(shù)據(jù)流圖管道-過濾器風(fēng)格的優(yōu)點(一)由于每個組件的行為不受其他組件的影響,整個系統(tǒng)的行為易于理解系統(tǒng)中的組件具有良好的隱蔽性和高內(nèi)聚、低耦合的特點支持軟件復(fù)用:允許設(shè)計者將整個系統(tǒng)的輸入/輸出行為看成是多個過濾器的行為的簡單合成;只要提供適合在兩個過濾器之間傳送的數(shù)據(jù),任何兩個過濾器都可被連接起來;系統(tǒng)維護(hù)和增強(qiáng)系統(tǒng)性能簡單:新的過濾器可以添加到現(xiàn)有系統(tǒng)中來,舊的可以被改進(jìn)的過濾器替換掉;管道-過濾器風(fēng)格的優(yōu)點(二)允許對一些如吞吐量、死鎖等屬性的分析;支持并行執(zhí)行:每個過濾器是作為一個單獨的任務(wù)完成,因此可與其它任務(wù)并行執(zhí)行。管道-過濾器風(fēng)格的缺點(一)通常導(dǎo)致進(jìn)程成為批處理的結(jié)構(gòu)這是因為雖然過濾器可增量式地處理數(shù)據(jù),但它們是獨立的,所以設(shè)計者必須將每個過濾器看成一個完整的從輸入到輸出的轉(zhuǎn)換;不適合處理交互的應(yīng)用當(dāng)需要增量地顯示改變時,這個問題尤為嚴(yán)重;管道-過濾器風(fēng)格的缺點(二)在數(shù)據(jù)傳輸上沒有通用的標(biāo)準(zhǔn),每個過濾器都增加了解析和合成數(shù)據(jù)的工作,這樣就導(dǎo)致了系統(tǒng)性能下降,并增加了編寫過濾器的復(fù)雜性。

絕大部分處理時間消耗在格式轉(zhuǎn)換上(需要對數(shù)據(jù)傳輸進(jìn)行特定的處理時,會導(dǎo)致對于每個過濾器的解析輸入和格式化輸出要做更多的工作,帶來系統(tǒng)復(fù)雜性的上升)批處理與管道-過濾器的比較相似點:把任務(wù)分解成為一系列固定順序的計算單元

彼此間只通過數(shù)據(jù)傳遞交互批處理與管道-過濾器的比較不同點:BatchSequentialPipe-and-Filter整體傳遞數(shù)據(jù)組件粒度較大延遲高,實時性差無并發(fā)增量組件粒度較小實時性好可并發(fā)管道-過濾器風(fēng)格的例子:DOSDOS中也有管道命令。DOS允許在命令中出現(xiàn)用豎線字符“|”分開的多個命令,將符號“|”前面的命令的輸出,作為“|”之后命令的輸入,這就是“管道功能”,豎線字符“|”就是管道操作符。例如,命令“dir|more”使得當(dāng)前目錄列表在屏幕上逐屏顯示。dir的輸出的是整個目錄列表,它不出現(xiàn)在屏幕上而是由于符號“|”的規(guī)定,成為下一個命令more的輸入,more命令則將其輸入一屏一屏地顯示,成為命令行的輸出。Java管道流JavaI/O流中的管道流類PipedInputStream和PipedOutputStream可以方便地實現(xiàn)管道-過濾器體系結(jié)構(gòu),這兩個類的實例對象要通過connect方法連接。JavaI/O流中有管道流類PipedInputStream、PipedOutputStream和PipedReader、PipedWriter,它們的對象總是成對出現(xiàn)。寫入類PipedOutputStream的對象的數(shù)據(jù),可以由與之相連接的類PipedInputStream的對象讀出;寫入類PipedWriter的對象的數(shù)據(jù),可以由與之相連接的類PipedReader的對象讀出。可見,這兩組管道流類與管道組件的要求相吻合,可以借助它們實現(xiàn)管道。所以,使用它們,可以方便地實現(xiàn)管道-過濾器體系結(jié)構(gòu)。這兩個類的實例對象通過connect()方法連接。Java管道流下面程序的功能是sender發(fā)送“Hello,receiver!I`msender”給receiver,然后receiver接受后顯示出來并且在前面加上“thefollowingisfromsender”的信息。管道流內(nèi)部在實現(xiàn)時還有大量的對同步數(shù)據(jù)的處理,管道輸出流和管道輸入流執(zhí)行時不能互相阻塞,所以一般要開啟獨立線程分別執(zhí)行,順便復(fù)習(xí)了多線程操作。importjava.io.*;importjava.util.*;publicclassTestPiped{publicstaticvoidmain(String[]args){senders=newsender();receiverr=newreceiver();PipedOutputStreamout=s.getOut();PipedInputStreamin=r.getIn();try{in.connect(out);s.start();r.start();}catch(Exceptione){e.printStackTrace();}}}classsenderextendsThread{PipedOutputStreamout=newPipedOutputStream();publicPipedOutputStreamgetOut(){returnout;}publicvoidrun(){Stringstr="Hello,receiver!I`msender\n";try{out.write(str.getBytes());out.close();}catch(Exceptione){e.printStackTrace();}}}classreceiverextendsThread{PipedInputStreamin=newPipedInputStream();publicPipedInputStreamgetIn(){returnin;}publicvoidrun(){byte[]buf=newbyte[1024];try{intlen=in.read(buf);System.out.println("thefollowingisfromsender:\n“+newString(buf,0,len));in.close();}catch(Exceptione){e.printStackTrace();}}}程序的執(zhí)行結(jié)果:

thefollowingisfromsender:Hello,receiver!I`msender組件對數(shù)據(jù)的處理的過濾器sender和receiver。連接件關(guān)鍵語句(1)PipedOutputStreamout=s.getOut();這條語句作用是發(fā)送端送出數(shù)據(jù)。(2)PipedInputStreamin=r.getIn();這條語句作用是接收端接收數(shù)據(jù)。(3)in.connect(out);這條語句作用是銜接管道兩端。3.3基于事件的隱式調(diào)用風(fēng)格顯式調(diào)用vs.隱式調(diào)用顯式調(diào)用各個組件之間的互動是由顯性調(diào)用函數(shù)或程序完成的。調(diào)用過程與次序是固定的、預(yù)先設(shè)定的。隱式調(diào)用在很多情況下,軟件更多的變成被動性系統(tǒng),組件持續(xù)的與其所處的環(huán)境打交道,但并不知道確切的交互次序3.3.1基于事件的隱式調(diào)用隱式調(diào)用:組件不直接調(diào)用一個過程一個組件(事件源)可以觸發(fā)或廣播一個或多個事件。系統(tǒng)中的其它組件(事件處理器)可以注冊自己感興趣的事件,并將自己的某個過程與相應(yīng)的事件進(jìn)行關(guān)聯(lián)。當(dāng)一個事件被發(fā)布,系統(tǒng)(事件管理器)自動調(diào)用在該事件中注冊的所有過程。這樣,一個事件的觸發(fā)就導(dǎo)致了另一模塊中的過程的調(diào)用。這種系統(tǒng),稱為基于事件的系統(tǒng)(Event-basedsystem),采用隱式調(diào)用(Implicitinvocation)的方式。基本組件:對象或過程,并分類為以下更小的組件

過程或函數(shù),充當(dāng)事件源或事件處理器的角色事件連接件:事件-過程綁定過程(事件處理器,事件的接收和處理方)向特定的事件進(jìn)行注冊;組件(事件源)發(fā)布事件;當(dāng)某些事件被發(fā)布(觸發(fā))時,向其注冊的過程被隱式調(diào)用;調(diào)用的次序是不確定的;基于事件的隱式調(diào)用特點優(yōu)點為軟件復(fù)用提供了強(qiáng)大的支持,功能擴(kuò)展比較容易當(dāng)需要將一個組件加入現(xiàn)存系統(tǒng)中時,只需將它注冊到系統(tǒng)的事件中數(shù)據(jù)通過接口訪問,數(shù)據(jù)格式的變化不會影響其他部分各模塊之間的調(diào)用隱式化,從而復(fù)用性提高為系統(tǒng)動態(tài)演化帶來了方便組件獨立存在,當(dāng)用一個組件代替另一個組件時,不會影響到其它組件的接口健壯性一個組件出錯將不會影響其他組件支持實現(xiàn)交互式系統(tǒng)(用戶輸入/網(wǎng)絡(luò)通訊)異步執(zhí)行,不必同步等待執(zhí)行結(jié)果對事件的并發(fā)處理將提高系統(tǒng)性能;缺點分布式控制方式使系統(tǒng)的同步、驗證和調(diào)試變得異常困難:組件放棄了對系統(tǒng)計算的控制,難以控制各模塊之間的處理次序。一個組件觸發(fā)一個事件時,不能確定其它組件是否會響應(yīng)它。而且即使它知道事件注冊了哪些組件的構(gòu)成,它也不能保證這些過程被調(diào)用的順序。既然過程的語義必須依賴于被觸發(fā)事件的上下文約束,關(guān)于正確性的推理則難以保證。傳統(tǒng)的基于先驗和后驗條件的驗證變得不可能。數(shù)據(jù)交換的問題:數(shù)據(jù)可通過事件直接在系統(tǒng)間傳遞(無調(diào)度模塊時)。但在具有獨立調(diào)度模塊的事件系統(tǒng)中,數(shù)據(jù)則需要經(jīng)過調(diào)度模塊的傳遞(基于事件的系統(tǒng)必須依靠一個共享的倉庫進(jìn)行交互)。在這些情況下,全局性能和資源管理成為了系統(tǒng)的瓶頸。使用更多的存儲空間基于事件的隱式調(diào)用風(fēng)格應(yīng)用領(lǐng)域基于事件的隱式調(diào)用風(fēng)格常常被用于如下領(lǐng)域:(1)在程序設(shè)計環(huán)境中用于集成各種工具。(2)在數(shù)據(jù)庫管理系統(tǒng)中用于檢查數(shù)據(jù)庫的一致性約束條件。(3)在用戶界面中分離數(shù)據(jù)和表示。(4)在編輯器中支持語法檢查。例如在某系統(tǒng)中,編輯器和變量監(jiān)視器可以登記相應(yīng)Debugger的斷點事件。當(dāng)Debugger在斷點處停下時,它聲明該事件,由系統(tǒng)自動調(diào)用處理程序,如編輯程序可以顯示到斷點,變量監(jiān)視器刷新變量數(shù)值。而Debugger本身只聲明事件,并不關(guān)心哪些過程會啟動,也不關(guān)心這些過程做什么處理。3.3.2JAVA的事件處理處理事件的一般步驟是注冊監(jiān)聽器以監(jiān)聽事件源產(chǎn)生的事件(如通過ActionListener來響應(yīng)用戶點擊按鈕);定義處理事件的方法(如在ActionListener中的actionPerformed中定義相應(yīng)方法)。importjava.awt.*;importjava.awt.event.*; //引入java.awt.event包處理事件classBtnLabelActionextendsFrameimplementsActionListener{//聲明窗口類(BtnLabelAction)并實現(xiàn)動作事件接口(ActionListener)

Labelprompt;Buttonbtn;voidCreateWindow(){setTitle("MyButton");prompt=newLabel("你好");//創(chuàng)建標(biāo)簽對象

btn=newButton("操作"); //創(chuàng)建按鈕對象

setLayout(newFlowLayout());//布局設(shè)計,用于安排按鈕、標(biāo)簽的位置

add(prompt); //將標(biāo)簽放入容器

add(btn); //將按鈕放入容器

btn.addActionListener(this); //將監(jiān)聽器(窗體對象本身)注冊給按鈕對象

setSize(300,100);setVisible(true);}

publicvoidactionPerformed(ActionEvente){//接口ActionListener的事件處理方法if(e.getSource()==btn)//判斷動作事件是否是由按鈕btn引發(fā)的

if(prompt.getText()=="你好")prompt.setText("再見");elseprompt.setText("你好");}}publicclassex604{publicstaticvoidmain(Stringargs[]){BtnLabelActionbla=newBtnLabelAction();事件源

bla.CreateWindow();}}事件源注冊:btn.addActionListener(監(jiān)聽器對象);監(jiān)聽器動作事件處理方法:publicvoidactionPerformed(ActionEvente)動作事件(ActionEvent)先注冊監(jiān)聽器觸發(fā)事件調(diào)用并傳遞參數(shù)e組件注冊方法addActionListener()處理事件的方法actionPerformed()發(fā)生的事件ActionEvente事件源btn監(jiān)聽器this(窗體對象本身,實現(xiàn)了Actionlistener接口的類的對象)。連接件(1)btn.addActionListener(this):將事件源按鈕對象注冊到監(jiān)聽器(this,窗體對象本身implementsActionlistener)。(2)系統(tǒng)定義對事件的處理方法,發(fā)生的事件為參數(shù):publicvoidactionPerformed(ActionEvente)。(3)點擊btn,觸發(fā)ActionEvent事件,事件管理器(實現(xiàn)了Actionlistener接口的類,本程序為窗體對象本身this)會根據(jù)發(fā)生的ActionEvent事件,自動調(diào)用actionPerformed()方法,執(zhí)行方法體中的語句。3.4層次風(fēng)格3.4.1層次風(fēng)格概念層次系統(tǒng)在層次系統(tǒng)中,系統(tǒng)被組織成若干個層次,每個層次由一系列組件組成下層組件向上層組件提供服務(wù)上層組件被看作是下層組件的客戶核心層-功能層-應(yīng)用層層次軟件體系風(fēng)格基本組件:各層次內(nèi)部包含的組件連接件:層間的交互協(xié)議拓?fù)浣Y(jié)構(gòu):分層拓?fù)浼s束:對相鄰層間交互的約束集中式部署(Mainframe)分布式部署(Distributed)優(yōu)點支持基于抽象程度遞增的系統(tǒng)設(shè)計,有利于設(shè)計者對一個復(fù)雜系統(tǒng)進(jìn)行分解;局部依賴性,因為每一層至多和相鄰的上下層交互,因此功能的改變通常影響相鄰的上下層;可復(fù)用性,如果某獨立層保證了功能的完整性并且提供了文檔化的接口,便可在多個語境中復(fù)用??商鎿Q性,只要提供的服務(wù)接口定義不變,同一層的不同實現(xiàn)可以交換使用。這樣,就可以定義一組標(biāo)準(zhǔn)的接口,而允許各種不同的實現(xiàn)方法。對標(biāo)準(zhǔn)化的支持。清晰定義并且廣泛接受的抽象層次能夠促進(jìn)實現(xiàn)標(biāo)準(zhǔn)化的任務(wù)和接口開發(fā),同樣接口的不同實現(xiàn)能夠互換使用??蓽y試性。具有定義明確的層接口以及交換層接口的各個實現(xiàn)的能力提高了可測試性。缺點并不是每個系統(tǒng)都可以很容易地劃分為分層的模式,甚至即使一個系統(tǒng)的邏輯結(jié)構(gòu)是層次化的,出于對系統(tǒng)性能的考慮,系統(tǒng)設(shè)計師不得不把一些低級或高級的功能綜合起來;效率的降低:由分層風(fēng)格構(gòu)成的系統(tǒng),運行效率往往低于整體結(jié)構(gòu)。在上層中的服務(wù)如果有很多依賴于最底層,則相關(guān)的數(shù)據(jù)必須通過一些中間層的若干次轉(zhuǎn)化,才能傳到;很難找到合適的、正確的層次抽象方法:層數(shù)太少,分層不能完全發(fā)揮這種風(fēng)格的可復(fù)用性、可更改性和可移植性上的潛力。層數(shù)過多,則引入不必要的復(fù)雜性和層間隔離冗余以及層間傳輸開銷。目前,沒有可行的廣為人們所認(rèn)可的層粒度的確定和層任務(wù)的分配方法。3.4.2實例ISO/OSI網(wǎng)絡(luò)的分層模型傳輸介質(zhì)接口通信控制項(通信子網(wǎng))應(yīng)用層物理傳輸介質(zhì)應(yīng)用層表示層表示層會話層會話層傳輸層傳輸層網(wǎng)絡(luò)層網(wǎng)絡(luò)層數(shù)據(jù)鏈路層數(shù)據(jù)鏈路層物理層物理層應(yīng)用控制項(資源子網(wǎng))軟件自動測試系統(tǒng)該測試軟件被設(shè)計成三層第一層為圖形用戶界面(GUILayer),用于用戶選擇測試案例、用戶輸入以及顯示測試結(jié)果;第二層為測試案例層(TestcaseLayer),軟件測試工程師所編寫的測試案例都部署在該層;第三層為被測試軟件層(ProgramUnerTestLayer),包含所有被測試軟件。

在本設(shè)計中,用戶圖形界面層調(diào)用測試案例層,選擇執(zhí)行某個測試案例;測試案例層調(diào)用被測試軟件,調(diào)用某個或者幾個被測試程序。組件第一層里的TestingGUI類第二層里的Testcase接口、TestcaseBubble類、TestcaseHeap類、TestcaseInscrtion類、ResultVerification類第三層里的BubbleSort類、HeapSort類、InscrtSort類、SortAlgorithm接口。連接件(1)在第一層TestingGUI類中聲明了第二層TestcaseBubble類的對象、TestcaseHeap類的對象和TestcaseInsertion類的對象,并調(diào)用它們的execute()方法,第二層的各類的execute()方法將一個數(shù)組結(jié)果返回給第一層。(2)在第二層的TestcaseBubble類中聲明了第三層的BubbleSort類的對象,并調(diào)用該類中的sort方法;第三層的BubbleSort類的sort方法將對數(shù)組的排序結(jié)果返回給第二層。TestcaseHeap類和TestcaseInsertion類類似。3.5倉庫風(fēng)格

在倉庫風(fēng)格中,有兩種不同的組件:一個是中央數(shù)據(jù)結(jié)構(gòu),它說明當(dāng)前狀態(tài)。另一個是獨立組件的集合,它對中央數(shù)據(jù)結(jié)構(gòu)進(jìn)行操作。根據(jù)系統(tǒng)中數(shù)據(jù)和狀態(tài)的控制方法的不同,可以分為兩種類型。一種類型是傳統(tǒng)的數(shù)據(jù)庫體系結(jié)構(gòu),它是由輸入事務(wù)選擇進(jìn)行何種處理,并把執(zhí)行結(jié)果作為當(dāng)前狀態(tài)存儲到中央數(shù)據(jù)結(jié)構(gòu)中。另一種類型是黑板(blackboard)體系結(jié)構(gòu),它是由中央數(shù)據(jù)結(jié)構(gòu)的當(dāng)前狀態(tài)決定進(jìn)行何種處理。內(nèi)存計算知識源黑板(共享數(shù)據(jù))知識源知識源知識源直接存取黑板體系結(jié)構(gòu)是倉庫體系結(jié)構(gòu)的特殊化。它反映的是一種信息共享的系統(tǒng)——如同教室里的黑板一樣,有多個人讀也有多個人寫。內(nèi)存計算知識源黑板(共享數(shù)據(jù))知識源知識源知識源直接存取黑板系統(tǒng)通常由三部分組成:(1)知識源(knowledgesources,KSs)。軟件專家模塊,每個知識源提供應(yīng)用程序所需要的具體的專家知識。知識源之間不直接進(jìn)行通訊,只通過黑板來完成它們之間的交互。(2)黑板數(shù)據(jù)結(jié)構(gòu)(blackboard)。一個共享知識庫,包含了問題、部分解決方案、建議和已經(jīng)貢獻(xiàn)的信息。按照與應(yīng)用程序相關(guān)的層次來組織的解決問題的數(shù)據(jù)。黑板可以被認(rèn)為是一個動態(tài)的“庫”,知識源通過不斷地改變黑板數(shù)據(jù)來解決問題。(3)控制機(jī)制(controlshell)。知識源需要控制機(jī)制來保證以一種最有效和連貫的方式來工作,正如人類專家得有一個主持人來防止他們亂搶粉筆。控制完全由黑板的狀態(tài)驅(qū)動,黑板狀態(tài)的改變決定使用的特定知識。黑板系統(tǒng)的傳統(tǒng)應(yīng)用是信號處理領(lǐng)

溫馨提示

  • 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論