版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 分布式軟件體系結(jié)構(gòu)</b></p><p><b> 編寫目標(biāo):</b></p><p> 面向計(jì)算機(jī)專業(yè)高年級(jí)本科生與研究生的教程。</p><p> 可供從事基于Internet/Intranet的分布式軟件開發(fā)人員參考使用。</p><p><b>
2、; 要求讀者:</b></p><p> 已掌握面向?qū)ο蟪绦蛟O(shè)計(jì)方法與一門面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言(Java最佳)。</p><p> 具備軟件工程的基本知識(shí)。</p><p><b> 總體構(gòu)思:</b></p><p> 強(qiáng)調(diào)理論與實(shí)踐相結(jié)合:理論上以CORBA 2.4為模型,實(shí)踐中以VisiBro
3、ker for Java 4.0為工具。</p><p> 強(qiáng)調(diào)深度與廣度相結(jié)合:重點(diǎn)介紹CORBA的同時(shí),兼顧DCOM與EJB兩種模型,最后總結(jié)對(duì)比這三種典型體系結(jié)構(gòu)的特點(diǎn)。</p><p><b> 主要內(nèi)容:</b></p><p> 分布式計(jì)算的基本概念:從C/S過(guò)渡到分布式體系結(jié)構(gòu)、OMA體系結(jié)構(gòu)、CORBA基本概念。</
4、p><p> 分布式應(yīng)用程序的開發(fā):分布式應(yīng)用程序框架、用IDL編寫對(duì)象接口、編寫服務(wù)程序與客戶程序、部署應(yīng)用程序。</p><p> 分布式計(jì)算更深入的課題:探討分布式應(yīng)用程序的可靠性、伸縮性、安全性、性能等課題可能提出的問(wèn)題以及解決途徑。</p><p> 不同體系結(jié)構(gòu)的比較:總結(jié)CORBA、DCOM、EJB、XML等特點(diǎn)。</p><p&
5、gt; 配合教學(xué)需要的內(nèi)容:在前言部分提供教學(xué)進(jìn)度供參考,每一章后均配有課后練習(xí)思考題和上機(jī)實(shí)習(xí)題。</p><p><b> 引 言</b></p><p> 分布式計(jì)算是當(dāng)前軟件開發(fā)技術(shù)的一個(gè)重要發(fā)展方向。C.A.R.Hoare指出:“分布式計(jì)算是一個(gè)具有重大理論與實(shí)踐意義的迷人課題,其迷人之處在于理論與實(shí)踐的同步發(fā)展,一方面實(shí)踐推動(dòng)了理論,另一方面理
6、論又指導(dǎo)著實(shí)踐?!北緯鵀樽x者介紹分布式計(jì)算領(lǐng)域的基本概念、開發(fā)過(guò)程、規(guī)范標(biāo)準(zhǔn)等內(nèi)容。</p><p> 分布式計(jì)算有兩種典型的應(yīng)用途徑。第一種應(yīng)用途徑是將分布式軟件系統(tǒng)看作直接反映了現(xiàn)實(shí)世界中的分布性,例如當(dāng)今許多業(yè)務(wù)處理流程通常呈現(xiàn)一種分布式運(yùn)作方式,負(fù)責(zé)加工或制造的工廠可能位于珠江三角洲一帶,而負(fù)責(zé)銷售與市場(chǎng)營(yíng)銷的部門則可能分別位于北京、上海和廣州,這時(shí)負(fù)責(zé)業(yè)務(wù)流程的軟件系統(tǒng)也可作相應(yīng)的分布式處理。第二種應(yīng)
7、用途徑主要用于改進(jìn)某些應(yīng)用程序的運(yùn)行性能,使它們比單進(jìn)程的集中式實(shí)現(xiàn)更具有效率,此時(shí)軟件系統(tǒng)的分布性并不是現(xiàn)實(shí)世界中分布性的映射,而是為充分利用額外的計(jì)算資源而人為引入的。</p><p> 在計(jì)算機(jī)硬件技術(shù)與網(wǎng)絡(luò)通信技術(shù)的支持下,應(yīng)用需求驅(qū)使計(jì)算機(jī)軟件的規(guī)模與復(fù)雜度不斷增長(zhǎng)。面對(duì)這種情況,對(duì)整個(gè)軟件系統(tǒng)的體系結(jié)構(gòu)進(jìn)行分析與設(shè)計(jì)就遠(yuǎn)遠(yuǎn)重要于對(duì)算法與數(shù)據(jù)結(jié)構(gòu)的選擇。軟件體系結(jié)構(gòu)關(guān)心的正是整個(gè)軟件系統(tǒng)的結(jié)構(gòu),它決定
8、了一個(gè)軟件系統(tǒng)由什么樣的組件組成,以及這些組件之間的交互關(guān)系如何。典型的軟件體系結(jié)構(gòu)風(fēng)格有設(shè)計(jì)圖形用戶界面常用的事件驅(qū)動(dòng)風(fēng)格、操作系統(tǒng)常用的層次化設(shè)計(jì)、設(shè)計(jì)編譯程序常用的管道與過(guò)濾器風(fēng)格、許多應(yīng)用程序都會(huì)使用的面向?qū)ο箫L(fēng)格等。</p><p> 分布式軟件系統(tǒng)通?;诳蛻魴C(jī)/服務(wù)器風(fēng)格,其中客戶程序提出信息或服務(wù)的請(qǐng)示,而服務(wù)程序提供這些信息或服務(wù)。客戶機(jī)/服務(wù)器計(jì)算模型的發(fā)展大約經(jīng)歷了三個(gè)里程碑:局域網(wǎng)文件服
9、務(wù)器、數(shù)據(jù)庫(kù)服務(wù)器以及分布式對(duì)象。由于當(dāng)前面向?qū)ο蠹夹g(shù)幾乎已滲透到軟件開發(fā)的每一個(gè)角落,先進(jìn)的分布式軟件開發(fā)方法當(dāng)然離不開與面向?qū)ο蠹夹g(shù)的結(jié)合,因而分布式軟件體系結(jié)構(gòu)通常是客戶機(jī)/服務(wù)器風(fēng)格與面向?qū)ο箫L(fēng)格的有效組合,典型的例子有OMG的公共對(duì)象請(qǐng)求代理體系結(jié)構(gòu)(CORBA)、Microsoft的分布式組件對(duì)象模型(DCOM)、Sun Microsystems的企業(yè)JavaBeans(EJB)等。</p><p>
10、 在這些模型中,CORBA以其規(guī)范的嚴(yán)格性、供應(yīng)商的無(wú)關(guān)性和其他許多先進(jìn)的分布式計(jì)算特性成為我們教學(xué)的首選。在理論教學(xué)方面,我們可參考OMG發(fā)布的一系列規(guī)范和關(guān)于CORBA的豐富讀物;在課程實(shí)驗(yàn)方面,我們既可下載使用IONA Orbix、Inprise VisiBroker等商品化CORBA產(chǎn)品的30或60天試用版,也可使用OmniORB、TAO等免費(fèi)CORBA產(chǎn)品。相對(duì)于其他分布式計(jì)算模型而言,CORBA在理論更為嚴(yán)格與完善,即使讀
11、者采用的開發(fā)平臺(tái)未必是CORBA兼容的,CORBA中提出的許多問(wèn)題也應(yīng)加以考慮,并可借鑒CORBA提出的問(wèn)題解決方案。</p><p> 本書從軟件體系結(jié)構(gòu)的角度介紹分布式軟件系統(tǒng)分析與設(shè)計(jì)的基本概念,描述了分布式軟件的開發(fā)與布署過(guò)程,并探討分布式軟件的可靠性、性能、可伸縮性等高級(jí)概念。本書的主要內(nèi)容分為四個(gè)部分。</p><p> 第一部分“基本概念”介紹分布式計(jì)算中的基本概念與基本
12、原理,從客戶機(jī)/服務(wù)器計(jì)算模型過(guò)渡到真正的分布式計(jì)算模型,并掌握OMA與CORBA的基本概念。為避免為傳統(tǒng)集中式軟件的開發(fā)人員一次性引入太多分布式對(duì)象計(jì)算的新概念,我們需要一個(gè)過(guò)渡性介紹以實(shí)現(xiàn)循序漸進(jìn)的教學(xué)目標(biāo),Java RMI以其簡(jiǎn)單性與實(shí)用性自然進(jìn)入我們的視野。</p><p> 第二部分“開發(fā)過(guò)程”首先利用一個(gè)完整而簡(jiǎn)單的分布式應(yīng)用例子程序介紹一個(gè)典型CORBA應(yīng)用程序的開發(fā)過(guò)程,然后詳細(xì)討論如何利用接口
13、定義語(yǔ)言(OMG IDL)編寫對(duì)象接口,如何編寫服務(wù)端程序與客戶端程序,以及如何部署最終的應(yīng)用程序。</p><p> 第三部分“高級(jí)課題”探討分布式應(yīng)用程序中的高級(jí)課題,提出可能產(chǎn)生的問(wèn)題以及這些問(wèn)題的可能解決途徑,包括分布式環(huán)境下對(duì)象查找、如何提高分布式應(yīng)用程序的可靠性、如何提高服務(wù)端程序的可伸縮性等。</p><p> 第四部分“其他與展望”通過(guò)簡(jiǎn)介與對(duì)比其他分布式體系結(jié)構(gòu)(如D
14、COM、EJB、XML等)拓寬讀者在分布式計(jì)算領(lǐng)域的知識(shí)面,探討分布式計(jì)算進(jìn)一步的發(fā)展方向。</p><p> 本書可供從事基于Internet/Intranet的分布式軟件開發(fā)人員參考使用,也可作為計(jì)算機(jī)專業(yè)高年級(jí)本科生與研究生學(xué)習(xí)分布式計(jì)算課程的教材。本書假設(shè)讀者已掌握面向?qū)ο蟪绦蛟O(shè)計(jì)方法與Java語(yǔ)言,并具備面向?qū)ο筌浖こ痰幕局R(shí)。</p><p> 如果選用本書作為授課教材
15、,對(duì)具有面向?qū)ο蟪绦蛟O(shè)計(jì)基礎(chǔ)并熟練掌握C++和Java語(yǔ)言的學(xué)生宜講授60課內(nèi)學(xué)時(shí),安排課外實(shí)驗(yàn)36學(xué)時(shí),教學(xué)進(jìn)度安排可參考如下(括號(hào)中分別標(biāo)明了課內(nèi)學(xué)時(shí)數(shù)與課外實(shí)驗(yàn)學(xué)時(shí)數(shù)):第1章(6/6)、第2章(4/0)、第3章(4/6)、第4章(4/0)、第5章(8/6)、第6章(6/6)、第7章(2/0)、第8章(2/0)、第9章(4/0)、第10章(6/0)、第11章(6/6)、第12章(4/6),第四部分的第13至15章(4/0)。對(duì)于不
16、熟悉Java語(yǔ)言和Web應(yīng)用的學(xué)生宜講授80課內(nèi)學(xué)時(shí),安排課外實(shí)驗(yàn)40學(xué)時(shí)。本書課后練習(xí)中規(guī)模較大或復(fù)雜性較高的題目以星號(hào)“*”標(biāo)出,這些題目適合作為課程設(shè)計(jì)的選題。</p><p> 在即將由ACM/IEEE-CS修訂發(fā)布的《計(jì)算教學(xué)大綱2001(CC2001)》中,“以網(wǎng)絡(luò)為中心的計(jì)算(NC)”已成為14個(gè)知識(shí)領(lǐng)域之一,其中包含客戶機(jī)/服務(wù)器計(jì)算、開發(fā)Web應(yīng)用、通信與網(wǎng)絡(luò)、分布式對(duì)象系統(tǒng)、協(xié)作技術(shù)與群件等
17、專題。本書內(nèi)容覆蓋了該知識(shí)領(lǐng)域的許多專題。</p><p> 本書中所有例子程序均使用Inprise公司的VisiBroker for Java 4.0和WebGain公司的VisualCafé Enterprise Edition 4.0平臺(tái)開發(fā),這些例子很容易移植到其他開發(fā)平臺(tái)。讀者可從我們的教學(xué)網(wǎng)站http://www.selab.zsu.edu.cn下載這些例子程序的全部源代碼。</p&
18、gt;<p> 分布式軟件系統(tǒng)是軟件開發(fā)的一個(gè)新興領(lǐng)域,并且各種分布式計(jì)算模型還在不斷地迅速發(fā)展。由于作者水平有限,書中謬誤之處在所難免,懇請(qǐng)廣大讀者不吝批評(píng)指正。</p><p> 第一部分 基本概念</p><p> 客戶機(jī)/服務(wù)器體系結(jié)構(gòu)</p><p> 本章利用Java語(yǔ)言的遠(yuǎn)程方法調(diào)用RMI與數(shù)據(jù)庫(kù)接口JDBC開發(fā)一個(gè)簡(jiǎn)單的電話計(jì)
19、費(fèi)查詢分布式應(yīng)用程序,通過(guò)這個(gè)完整的例子幫助讀者復(fù)習(xí)客戶機(jī)/服務(wù)器體系結(jié)構(gòu)的基本概念,并分析與探討該應(yīng)用程序需要進(jìn)一步考慮與改進(jìn)的不足之處,從而引出分布式軟件體系結(jié)構(gòu)要解決的問(wèn)題。</p><p><b> 軟件設(shè)計(jì)的基本概念</b></p><p> 隱式地 vs 顯式地</p><p> 隱式地(implicitly)與顯式地(exp
20、licitily)是軟件開發(fā)技術(shù)中經(jīng)常出現(xiàn)的兩個(gè)修飾術(shù)語(yǔ),用于表示程序設(shè)計(jì)語(yǔ)言、編程工具或軟件開發(fā)環(huán)境等對(duì)軟件開發(fā)人員的兩種不同支持方式。例如一個(gè)采用面向?qū)ο蠓椒ㄍ瓿傻脑O(shè)計(jì)同樣也可以利用C語(yǔ)言實(shí)現(xiàn),然而C語(yǔ)言對(duì)面向?qū)ο笤O(shè)計(jì)的支持是一種隱式的方式,面向?qū)ο笤O(shè)計(jì)的許多概念在C語(yǔ)言中無(wú)法直接地表達(dá)出來(lái),顯然這種隱式支持遠(yuǎn)遠(yuǎn)比不上C++、Java、Ada、Eiffel、Smalltalk等面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言提供的顯式支持。</p>
21、<p> 軟件開發(fā)人員獲得顯式支持的本質(zhì)可看作是將許多原來(lái)必須由程序員動(dòng)手實(shí)現(xiàn)的任務(wù)交由更底層的編譯程序、開發(fā)工具或運(yùn)行環(huán)境完成。例如在數(shù)據(jù)庫(kù)管理系統(tǒng)的幫助下,應(yīng)用程序員開發(fā)數(shù)據(jù)處理應(yīng)用程序時(shí)減輕了許多數(shù)據(jù)定義、查詢、完整性、安全性等方面的負(fù)擔(dān)。程序設(shè)計(jì)技術(shù)或軟件開發(fā)技術(shù)的發(fā)展方向之一是不斷為軟件開發(fā)人員提供更完善、更有效的顯式支持。</p><p> 例如在C語(yǔ)言或Pascal語(yǔ)言中無(wú)法顯式地
22、描述一個(gè)求平方根函數(shù)square_root()中可能引發(fā)的異常(譬如計(jì)算對(duì)象是一個(gè)負(fù)數(shù)),而C++語(yǔ)言或Java語(yǔ)言允許在函數(shù)原型中顯式地將函數(shù)體可能引發(fā)的異常表達(dá)出來(lái),這種顯式表達(dá)使得編譯程序可幫助程序員檢查該函數(shù)體中是否真的可能引發(fā)這些異常,以及約束使用這些函數(shù)的程序必須處理哪些異常。此外,將異常作為函數(shù)原型的一部分也有助于使用函數(shù)的程序員更全面地理解這些函數(shù)的語(yǔ)法與語(yǔ)義。</p><p> 又如在面向?qū)ο?/p>
23、程序設(shè)計(jì)中一個(gè)實(shí)體除了屬性與行為外,還應(yīng)包含該實(shí)體的屬性與行為應(yīng)滿足的約束。譬如一個(gè)銀行帳戶ACCOUNT除了擁有帳戶標(biāo)識(shí)、存款余額等屬性以及存款、取款、查詢余額等行為之外,還至少必須滿足一個(gè)約束,即在帳戶生存期的任一時(shí)刻存款余額不得小于0(如果是允許透支的信用卡帳戶,則應(yīng)將約束修改為透支不得超過(guò)某一上限,而透支上限必須是帳戶的一個(gè)屬性)。在C++語(yǔ)言或Java語(yǔ)言中,程序員無(wú)法將這一約束顯式地表達(dá)出來(lái),只能在對(duì)象初始化、存款、取款等行
24、為的實(shí)現(xiàn)中隱式地表達(dá),使用這些組件的其他程序員也只能通過(guò)理解這些行為的實(shí)現(xiàn)才能了解到ACCOUNT的這種約束。當(dāng)然通過(guò)注釋將約束表達(dá)出來(lái)是一種良好的程序設(shè)計(jì)風(fēng)格,但編譯程序不能為此提供任何幫助。相比之下,Eiffel程序員可顯式地描述ACCOUNT必須滿足的約束,以及每一操作之前或之后必須滿足的條件,程序員不必再考慮正常條件之外的異常,而交由運(yùn)行環(huán)境負(fù)責(zé)引發(fā)相應(yīng)的異常。</p><p> 在分布式軟件開發(fā)中比傳
25、統(tǒng)的集中式軟件開發(fā)有更多的問(wèn)題需要解決,程序員可以自己動(dòng)手解決這些問(wèn)題,但更理想的情況是由底層的支持(如語(yǔ)言、工具、環(huán)境等)幫助程序員完成這些任務(wù)。本書著重討論在分布式軟件開發(fā)中需要解決的重要問(wèn)題,以及當(dāng)前的分布式軟件開發(fā)規(guī)范與產(chǎn)品對(duì)解決這些問(wèn)題提供的支持。隨著分布式軟件開發(fā)技術(shù)的發(fā)展與成熟,程序員將獲得越來(lái)越完善與有效的支持。</p><p> 對(duì)顯式支持與隱式支持的討論可以提醒我們,必須留意在分布式軟件開發(fā)
26、中存在哪些問(wèn)題需要解決,這些問(wèn)題并不會(huì)因?yàn)榈貌坏斤@式支持而消失,在只有隱式支持的情況下程序員仍要自行解決這些問(wèn)題。因而對(duì)解決關(guān)鍵問(wèn)題的顯式支持是評(píng)價(jià)與選擇分布式軟件的體系結(jié)構(gòu)規(guī)范、程序設(shè)計(jì)語(yǔ)言、開發(fā)工具與環(huán)境的一個(gè)重要因素。當(dāng)然更重要的一點(diǎn)是提醒我們,在軟件開發(fā)過(guò)程中應(yīng)考慮可為分布式軟件開發(fā)添加哪些新的顯式支持,從而為分布式軟件在我國(guó)的推廣應(yīng)用作出自己的貢獻(xiàn)。</p><p> 邏輯的 vs 物理的</p
27、><p> 邏輯的(logical)與物理的(physical)分別代表著兩個(gè)不同的抽象層次。早在10年前由IEEE-CS/ACM聯(lián)合制訂的《91’計(jì)算教學(xué)計(jì)劃》中,就將抽象層次列為計(jì)算機(jī)科學(xué)與工程專業(yè)學(xué)生必須掌握的一個(gè)核心概念,這一概念貫穿了計(jì)算機(jī)學(xué)科的眾多領(lǐng)域。</p><p> 抽象是人類認(rèn)知世界的最基本思維方式之一。羅素曾斷言:“發(fā)現(xiàn)一對(duì)雞、兩晝夜都是數(shù)2的實(shí)例,一定需要很多年代,
28、其中所包含的抽象程度確實(shí)不易達(dá)到;至于1是一個(gè)數(shù)的發(fā)現(xiàn),也必定很困難?!?lt;/p><p> 抽象源于人類自身控制復(fù)雜性能力的不足:我們無(wú)法同時(shí)把握太多的細(xì)節(jié),復(fù)雜的問(wèn)題迫使我們將一些相關(guān)的概念組織成不同的抽象層次。例如日常生活中的is-a關(guān)系是人們對(duì)概念進(jìn)行抽象和分類的結(jié)果,例如蘋果是一種水果,水果是一種植物等,生物學(xué)采用的界、門、綱、目、科、屬、種標(biāo)準(zhǔn)生物分類方法是這一思維方式的經(jīng)典應(yīng)用。將這種is-a關(guān)系在
29、程序中顯式地表達(dá)出來(lái)而形成的繼承機(jī)制,是面向?qū)ο蟪绦蛟O(shè)計(jì)最重要的特征之一。 在軟件設(shè)計(jì)中太容易找到抽象層次的實(shí)例,例如變量→類型、對(duì)象→類→抽象數(shù)據(jù)類型、實(shí)現(xiàn)→規(guī)格說(shuō)明、數(shù)據(jù)流圖分解與平衡等。</p><p> 邏輯層與物理層組織是一種常見的抽象層次。一個(gè)典型的C++程序從邏輯上看由m個(gè)類與1個(gè)主函數(shù)main()組成,但同樣的邏輯組織形式卻在物理上可根據(jù)不同需要組織為不同形式的文件模塊,整個(gè)程序既可能劃分為n1
30、個(gè)文件模塊,也可能劃分為n2個(gè)文件模塊。從不同的抽象層次來(lái)看,這兩個(gè)程序的物理組織形式雖然不同,但其邏輯組織形式卻是一樣的。</p><p> 又如在管理信息系統(tǒng)的開發(fā)過(guò)程中,系統(tǒng)分析的主要任務(wù)是根據(jù)現(xiàn)有管理信息系統(tǒng)的物理模型建立更高抽象層次的邏輯模型,在邏輯模型中拋棄了物理模型中那些開發(fā)者不關(guān)心的細(xì)節(jié),僅表達(dá)了系統(tǒng)邊界之內(nèi)用戶最關(guān)心的內(nèi)容,這一建模過(guò)程的本質(zhì)就是一個(gè)抽象過(guò)程。系統(tǒng)分析員通過(guò)對(duì)邏輯模型的研究與改
31、進(jìn),進(jìn)一步實(shí)現(xiàn)在計(jì)算機(jī)平臺(tái)上的一個(gè)新的物理模型。</p><p> 在分布式軟件系統(tǒng)中,有許多機(jī)制雖然與傳統(tǒng)的集中式軟件在物理層次表現(xiàn)出很大差異,但從邏輯層次上看它們卻是統(tǒng)一的,例如普通函數(shù)調(diào)用與遠(yuǎn)程過(guò)程調(diào)用(RPC)、對(duì)象消息傳遞與遠(yuǎn)程方法調(diào)用(RMI)、接口與實(shí)現(xiàn)的分離、同一接口多種實(shí)現(xiàn)等。因而在分布式軟件體系結(jié)構(gòu)的學(xué)習(xí)與研究中,利用不同的抽象層次可幫助我們從更高層次掌握分布式軟件系統(tǒng)的各種機(jī)制,并且可以用
32、一種統(tǒng)一的知識(shí)框架來(lái)理解分布式軟件與傳統(tǒng)的集中式軟件的基本概念、表示技術(shù)以及開發(fā)過(guò)程。</p><p> 同理,一個(gè)軟件系統(tǒng)在邏輯層次表現(xiàn)為分布式的,但在物理層次部署時(shí)卻可能是集中式的。對(duì)于同一個(gè)分布式軟件系統(tǒng),可以用一臺(tái)單機(jī)同時(shí)充當(dāng)客戶機(jī)與服務(wù)器,并包含了兩者之間的通信,從而讓我們有可能在家中的一臺(tái)電腦上就能學(xué)習(xí)開發(fā)與調(diào)試分布式應(yīng)用程序,然后再將這些應(yīng)用程序部署到真正的分布式運(yùn)行環(huán)境中。</p>
33、<p><b> 面向?qū)ο蠹夹g(shù)</b></p><p> 在二十世紀(jì)80年代興起的面向?qū)ο蠹夹g(shù)已在軟件生存期的各個(gè)階段取代傳統(tǒng)的結(jié)構(gòu)化方法,成為當(dāng)前軟件開發(fā)的主流技術(shù)。在分布式軟件開發(fā)領(lǐng)域也不例外。</p><p> 面向?qū)ο箝_發(fā)過(guò)程本質(zhì)上是一個(gè)建模過(guò)程。開發(fā)人員通過(guò)分析問(wèn)題域中實(shí)體的屬性、行為、約束等,抽象出能描述這些實(shí)體共同結(jié)構(gòu)與特征的概念,然后
34、在計(jì)算機(jī)中利用類建立這些概念的系統(tǒng)模型,再通過(guò)類創(chuàng)建具體的對(duì)象實(shí)例模擬問(wèn)題域的實(shí)體行為。面向?qū)ο箝_發(fā)方法強(qiáng)調(diào)將系統(tǒng)功能建立在系統(tǒng)模型之上,所有系統(tǒng)功能采用底層的系統(tǒng)模型提供的術(shù)語(yǔ)來(lái)表達(dá),從而提高了軟件系統(tǒng)的可擴(kuò)展性與可維護(hù)性。</p><p> 除了封裝與信息隱藏、數(shù)據(jù)抽象、模塊化等特征外,面向?qū)ο蠹夹g(shù)的最主要特色是繼承與多態(tài)性。繼承是日常生活中的is-a關(guān)系在程序中的顯式表達(dá),是重用數(shù)據(jù)與操作的重要手段。多態(tài)
35、性有十分廣泛的含義,這里主要是指運(yùn)行期間程序表現(xiàn)出來(lái)的多態(tài)性,它建立在繼承與動(dòng)態(tài)綁定的基礎(chǔ)上,使得一個(gè)對(duì)象可以具有多種不同的動(dòng)態(tài)類型,從而大大提高了面向?qū)ο蟪绦虻谋磉_(dá)能力。</p><p> 先進(jìn)的分布式軟件體系結(jié)構(gòu)必須與面向?qū)ο蠹夹g(shù)結(jié)合在一起,從而可分享面向?qū)ο蠹夹g(shù)帶來(lái)的眾多好處。例如由開放軟件基金會(huì)(OSF)于1992年發(fā)布的分布式計(jì)算環(huán)境(Distributed Computing Environment
36、,縮寫為DCE)采用的是遠(yuǎn)程過(guò)程調(diào)用(Remote Procedure Call,縮寫為RPC)技術(shù),RPC支持開發(fā)人員進(jìn)行結(jié)構(gòu)化程序設(shè)計(jì),使得客戶程序可以像調(diào)用本地過(guò)程一樣調(diào)用服務(wù)程序中的過(guò)程。而由Sun Microsystems于1996年發(fā)布的遠(yuǎn)程方法調(diào)用(Remote Method Invocation,縮寫為RMI)技術(shù)是一種分布式對(duì)象模型,保持了Java語(yǔ)言的對(duì)象語(yǔ)義,支持分布式應(yīng)用程序員進(jìn)行面向?qū)ο蟪绦蛟O(shè)計(jì),在客戶程序中可
37、以像將消息傳遞給本地對(duì)象一樣,將消息傳遞給服務(wù)程序中的對(duì)象。</p><p> 當(dāng)前幾種主流的分布式軟件體系結(jié)構(gòu)均融合了分布式計(jì)算與面向?qū)ο蠹夹g(shù),包括OMG的公共對(duì)象請(qǐng)求代理體系結(jié)構(gòu)(CORBA)、Microsoft的分布式組件對(duì)象模型(DCOM)、Sun Microsystems的企業(yè)版JavaBeans(EJB)等。</p><p><b> 軟件體系結(jié)構(gòu)</b&g
38、t;</p><p> 隨著計(jì)算機(jī)軟件系統(tǒng)的規(guī)模不斷增大并且系統(tǒng)復(fù)雜度不斷提高,在軟件開發(fā)過(guò)程中對(duì)整個(gè)軟件系統(tǒng)的體系結(jié)構(gòu)進(jìn)行分析與設(shè)計(jì)遠(yuǎn)比對(duì)算法與數(shù)據(jù)結(jié)構(gòu)的選擇更加重要。軟件體系結(jié)構(gòu)關(guān)心的正是整個(gè)軟件系統(tǒng)的結(jié)構(gòu),它決定一個(gè)軟件系統(tǒng)由什么樣的組件構(gòu)成,以及這些組件之間的交互關(guān)系如何,并提供一種模式指導(dǎo)組件的合成。盡管嚴(yán)格的形式化工作仍處于實(shí)驗(yàn)階段,軟件體系結(jié)構(gòu)在軟件工程中已扮演著越來(lái)越重要的角色。</p&g
39、t;<p> 典型的軟件體系結(jié)構(gòu)風(fēng)格有設(shè)計(jì)圖形用戶界面(GUI)常用的事件驅(qū)動(dòng)風(fēng)格、設(shè)計(jì)操作系統(tǒng)常用的層次化設(shè)計(jì)風(fēng)格、設(shè)計(jì)編譯程序常用的管道與過(guò)濾器風(fēng)格、設(shè)計(jì)分布式應(yīng)用程序常用的客戶機(jī)/服務(wù)器風(fēng)格等。一個(gè)實(shí)用的軟件系統(tǒng)通常是幾種典型體系結(jié)構(gòu)風(fēng)格的組合。</p><p> 分布式軟件系統(tǒng)通?;诳蛻魴C(jī)/服務(wù)器(client/server)模型,因而組成系統(tǒng)的最核心組件是客戶程序與服務(wù)程序,然而不同
40、的分布式軟件體系結(jié)構(gòu)還決定了各自不同的組件以及這些組件之間的交互方式。例如在OMG的CORBA模型中,存在若干稱為對(duì)象請(qǐng)求代理(ORB)的組件,這些組件之間采用因特網(wǎng)ORB間協(xié)議(IIOP)進(jìn)行通信;又如在OSF/DCE中,客戶程序與服務(wù)程序之間通過(guò)遠(yuǎn)程過(guò)程調(diào)用(RPC)進(jìn)行交互,參數(shù)與返回值的編碼采用外部數(shù)據(jù)表示(XDR)技術(shù),而Sun Microsystems的EJB則利用遠(yuǎn)程方法調(diào)用(RMI)進(jìn)行交互,參數(shù)與返回值的編碼采用Jav
41、a語(yǔ)言專用的對(duì)象串行化技術(shù)。</p><p> 本書主要從軟件體系結(jié)構(gòu)的角度探討分布式軟件系統(tǒng)的有關(guān)課題。一個(gè)分布式應(yīng)用系統(tǒng)在軟件體系結(jié)構(gòu)層次需要考慮的問(wèn)題包括如何將組件合成系統(tǒng)、如何將功能指派到設(shè)計(jì)元素、通信與同步協(xié)議、全局控制結(jié)構(gòu)、物理的分布、可伸縮性與可靠性等。</p><p><b> 客戶機(jī)/服務(wù)器模型</b></p><p>&
42、lt;b> 客戶機(jī)與服務(wù)器</b></p><p> 在二十世紀(jì)90年代興起的客戶機(jī)/服務(wù)器數(shù)據(jù)庫(kù)技術(shù)是自70年代關(guān)系數(shù)據(jù)庫(kù)技術(shù)以來(lái)數(shù)據(jù)庫(kù)技術(shù)的一次重大飛躍。由于在客戶機(jī)/服務(wù)器數(shù)據(jù)庫(kù)系統(tǒng)中將系統(tǒng)的處理任務(wù)劃分為客戶系統(tǒng)與數(shù)據(jù)庫(kù)服務(wù)器兩端,因而大量的數(shù)據(jù)庫(kù)操作可在后端運(yùn)行,工作站只需能夠運(yùn)行前端軟件即可。盡管客戶機(jī)/服務(wù)器系統(tǒng)比傳統(tǒng)的集中式系統(tǒng)更復(fù)雜,然而這一新的計(jì)算模型帶來(lái)的優(yōu)勢(shì)是顯而易見
43、的,例如減輕了網(wǎng)絡(luò)傳輸負(fù)擔(dān),實(shí)現(xiàn)了工作站無(wú)關(guān)性,更方便維護(hù)數(shù)據(jù)的完整性等。</p><p> 其實(shí)客戶機(jī)/服務(wù)器體系結(jié)構(gòu)并不僅僅局限于數(shù)據(jù)庫(kù)應(yīng)用,這種計(jì)算模型有著更廣義的定義。如果一個(gè)系統(tǒng)被劃分為兩類不同的但相互聯(lián)系的組成部分,其中一方提出對(duì)信息或服務(wù)的請(qǐng)求(稱為客戶機(jī)),而另一方提供這種信息或服務(wù)(稱為服務(wù)器),那么這種體系結(jié)構(gòu)即可看作是一種客戶機(jī)/服務(wù)器計(jì)算模型。按照這一定義,局域網(wǎng)中的工作站與文件服務(wù)器之
44、間是一種客戶機(jī)/服務(wù)器模型,其中工作站向文件服務(wù)器發(fā)送服務(wù)請(qǐng)求,例如要求訪問(wèn)文件或網(wǎng)絡(luò)打印等,文件服務(wù)器接收這些請(qǐng)求后為工作站提供這些服務(wù)。因特網(wǎng)的許多應(yīng)用程序都采用客戶機(jī)/服務(wù)器模型,例如Web瀏覽器與服務(wù)器、電子郵件客戶程序與服務(wù)程序、FTP客戶程序與服務(wù)程序等。</p><p> 客戶機(jī)與服務(wù)器是一個(gè)相對(duì)的概念,一個(gè)服務(wù)器可能是另一個(gè)服務(wù)器的客戶機(jī),一個(gè)客戶機(jī)也可能是另一個(gè)客戶機(jī)的服務(wù)器。客戶機(jī)與服務(wù)器的
45、劃分可以是物理層次的,例如局域網(wǎng)中的工作站與文件服務(wù)器通常是由兩臺(tái)不同的計(jì)算機(jī)系統(tǒng)擔(dān)任;客戶機(jī)與服務(wù)器的劃分也可以是邏輯層次的,這時(shí)我們經(jīng)常又將這兩端分別稱為客戶程序與服務(wù)程序。</p><p> 一個(gè)常見的簡(jiǎn)單例子是在過(guò)程式程序設(shè)計(jì)中,執(zhí)行函數(shù)調(diào)用表達(dá)式的子程序與實(shí)現(xiàn)函數(shù)體的子程序可看作一種客戶機(jī)/服務(wù)器模型,其中函數(shù)實(shí)現(xiàn)方是服務(wù)程序,函數(shù)調(diào)用方是客戶程序。在面向?qū)ο蟪绦蛟O(shè)計(jì)中,消息傳遞可看作客戶程序向服務(wù)程
46、序發(fā)送服務(wù)請(qǐng)求的過(guò)程,發(fā)送消息的是客戶程序,接收并處理消息的服務(wù)程序。</p><p> 在普通的函數(shù)調(diào)用中,對(duì)于函數(shù)實(shí)現(xiàn)與函數(shù)調(diào)用雙方最為重要的是兩者之間的接口(又稱界面,即函數(shù)原型說(shuō)明)以及通信協(xié)議(例如雙方對(duì)調(diào)用風(fēng)格的約定,決定采用C還是Pascal的調(diào)用風(fēng)格)??蛻舫绦蚺c服務(wù)程序之間的接口描述越清晰,對(duì)編寫客戶程序與服務(wù)程序的開發(fā)人員幫助越大,同時(shí)各種編程工具或可重用組件管理工具越有可能為開發(fā)人員提供有
47、力支持。函數(shù)原型一般都包含了函數(shù)名字、返回值類型、參數(shù)個(gè)數(shù)與類型等,更完善的接口還可能包括可能引發(fā)的異常、必須滿足的前置條件與后置條件等。這些接口的內(nèi)容都是語(yǔ)法層面的,如果有朝一日能提供語(yǔ)義層面的接口描述,軟件開發(fā)人員將看到軟件構(gòu)造自動(dòng)化的曙光,這當(dāng)然還要依賴于形式語(yǔ)義學(xué)研究有進(jìn)一步的突破。</p><p> 分布式軟件系統(tǒng)絕大多數(shù)采用客戶機(jī)/服務(wù)器體系結(jié)構(gòu),其中最重要的仍是上述接口與通信協(xié)議的問(wèn)題,只不過(guò)由于
48、客戶端與服務(wù)端在物理層次上的分離,導(dǎo)致通信協(xié)議更加復(fù)雜,并且可靠性、安全性、性能等因素顯得更加突出。</p><p> 客戶端與服務(wù)端的分離</p><p> 分布式軟件與傳統(tǒng)的集中式軟件主要區(qū)別在于強(qiáng)調(diào)客戶端與服務(wù)端在地理位置上的分離。雖然分布式軟件與集中式軟件在邏輯層次有許多方面是一致的,但在物理層次兩者仍有許多重大區(qū)別。</p><p> 在分布式軟件系
49、統(tǒng)中客戶端與服務(wù)端的物理分離可帶來(lái)許多好處。首先,整個(gè)系統(tǒng)的所有計(jì)算任務(wù)可在客戶端與服務(wù)端兩邊進(jìn)行負(fù)載重新分布,使得RISC工作站與微機(jī)建立的計(jì)算機(jī)網(wǎng)絡(luò)系統(tǒng)可以完成以前只有價(jià)格昂貴的大型機(jī)(mainframe)才可勝任的工作,實(shí)現(xiàn)企業(yè)計(jì)算規(guī)模的下行(downsizing);而與傳統(tǒng)的基于局域網(wǎng)的應(yīng)用系統(tǒng)相比,客戶端與服務(wù)端的分離大大減少了網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量,可有效地提高系統(tǒng)的運(yùn)行效率,實(shí)現(xiàn)企業(yè)計(jì)算規(guī)模的上行(upsizing)。其次,這種
50、新的計(jì)算模型更好地支持了平臺(tái)無(wú)關(guān)性,客戶端既可以運(yùn)行在IBM PC兼容微機(jī)、Macintosh微機(jī)、RISC工作站等不同機(jī)型,也可以運(yùn)行Microsoft Windows、IBM OS/2、Apple System 8、各種版本的Unix等不同操作系統(tǒng),還支持TCP/IC、IPX/SPX、NetBEUI等不同網(wǎng)絡(luò)協(xié)議。此外,采用客戶機(jī)/服務(wù)器計(jì)算模型的軟件系統(tǒng)具有更好的可擴(kuò)充性,例如可在服務(wù)端功能不變的前提下對(duì)服務(wù)端程序進(jìn)行改進(jìn)或擴(kuò)充,
51、而這種改進(jìn)與擴(kuò)充不會(huì)影響到客戶端的應(yīng)用程序。</p><p> 當(dāng)然這種分離也會(huì)帶來(lái)一些新問(wèn)題,對(duì)于軟件開發(fā)人員而言,最主要的問(wèn)題是分布式軟件系統(tǒng)通常比集中式軟件系統(tǒng)更加復(fù)雜。例如開發(fā)人員不得不分別開發(fā)客戶端與服務(wù)端的應(yīng)用程序,并力求保持兩端應(yīng)用程序的一致性,軟件系統(tǒng)的部署與維護(hù)也更加困難。此外,設(shè)計(jì)分布式軟件系統(tǒng)時(shí)比設(shè)計(jì)集中式軟件系統(tǒng)需要考慮更多的可靠性、安全性、性能等軟件質(zhì)量要素。</p>&
52、lt;p> 本書將主要討論客戶機(jī)/服務(wù)器體系結(jié)構(gòu)設(shè)計(jì)中的這些復(fù)雜問(wèn)題,包括如何更好地顯式表達(dá)客戶端與服務(wù)端雙方的公共接口,客戶端應(yīng)用程序與服務(wù)端應(yīng)用程序雙方如何進(jìn)行通信,客戶端應(yīng)用程序如何查找服務(wù)程序,如何保證服務(wù)端應(yīng)用程序的可用性等等。</p><p><b> 兩層模型與多層模型</b></p><p> 典型的客戶機(jī)/服務(wù)器體系結(jié)構(gòu)又稱為兩層(2-t
53、ier)模型。在兩層模型的設(shè)計(jì)中,由客戶應(yīng)用程序直接處理對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)。因而每一臺(tái)運(yùn)行客戶應(yīng)用程序的客戶機(jī)都必須安裝數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序,增加了系統(tǒng)安裝與維護(hù)的工作量。同時(shí),數(shù)據(jù)庫(kù)由眾多客戶程序直接訪問(wèn),導(dǎo)致數(shù)據(jù)的完整性與安全性難以維護(hù)。</p><p> 為提高數(shù)據(jù)的安全性與系統(tǒng)的可擴(kuò)充性,可在兩層模型的基礎(chǔ)上考慮采用三層(3-tier)或多層(N-tier)設(shè)計(jì)模型,將數(shù)據(jù)庫(kù)訪問(wèn)分布在一個(gè)或多個(gè)中間層。客戶程序與
54、數(shù)據(jù)庫(kù)的連接被中間層屏蔽,客戶程序只能通過(guò)中間層間接地訪問(wèn)數(shù)據(jù)庫(kù)。中間層可能運(yùn)行在不同于客戶機(jī)的其他機(jī)器上,經(jīng)過(guò)合理的任務(wù)劃分與物理部署后,可使得整個(gè)系統(tǒng)的工作負(fù)載更趨均衡,從而提高整個(gè)系統(tǒng)的運(yùn)行效率。</p><p> 這些位于中間層的中間件(middleware)又稱應(yīng)用服務(wù)程序(application server),因?yàn)樗鼈儗?shí)際上表達(dá)了一個(gè)企業(yè)處理信息的主要業(yè)務(wù)邏輯(business logic),即企
55、業(yè)的系統(tǒng)模型與功能模型,而客戶程序僅實(shí)現(xiàn)圖形用戶界面,完成終端用戶與業(yè)務(wù)邏輯之間的交互。</p><p> 從客戶程序的角度來(lái)看,中間件將企業(yè)的所有業(yè)務(wù)邏輯抽象為更高層次的應(yīng)用程序接口(API),客戶程序則通過(guò)這些API構(gòu)建整個(gè)企業(yè)的應(yīng)用系統(tǒng)。與典型的兩層模型相比,三層模型或多層模型可更好地支持對(duì)企業(yè)業(yè)務(wù)邏輯的集中控制與管理。</p><p><b> 一個(gè)簡(jiǎn)單的例子<
56、/b></p><p><b> 問(wèn)題背景</b></p><p> 電信收費(fèi)是當(dāng)前老百姓關(guān)心的熱點(diǎn)問(wèn)題,明明白白消費(fèi)是每一個(gè)消費(fèi)者的合理要求,但如果打印并郵寄每月話費(fèi)清單無(wú)疑會(huì)額外花費(fèi)大量的人力、物力與財(cái)力。隨著我國(guó)信息基礎(chǔ)設(shè)施的不斷完善,上網(wǎng)普及率越來(lái)越高,通過(guò)因特網(wǎng)查詢?cè)捹M(fèi)將是一條非??尚械耐緩健1拘」?jié)以一個(gè)簡(jiǎn)化的電話計(jì)費(fèi)查詢程序?yàn)槔?,向讀者介紹分布式
57、應(yīng)用程序的基本概念,并通過(guò)對(duì)這一簡(jiǎn)單應(yīng)用程序的討論引出分布式軟件體系結(jié)構(gòu)中需要考慮的更高級(jí)課題。</p><p> 該例子程序采用純Java語(yǔ)言編寫,利用JDBC/ODBC訪問(wèn)關(guān)系數(shù)據(jù)庫(kù),并采用遠(yuǎn)程方法調(diào)用RMI實(shí)現(xiàn)客戶程序與服務(wù)程序之間的交互??蛻舫绦蛑荒芡ㄟ^(guò)服務(wù)程序間接地訪問(wèn)關(guān)系數(shù)據(jù)庫(kù),因而該例子程序?qū)儆谝环N典型的三層設(shè)計(jì)模型。</p><p><b> 數(shù)據(jù)庫(kù)設(shè)計(jì)<
58、;/b></p><p> 根據(jù)數(shù)據(jù)庫(kù)設(shè)計(jì)原理,我們很容易得到如圖1.1所示的典型設(shè)計(jì)結(jié)果。</p><p> 數(shù)據(jù)庫(kù)Telephone</p><p> 表TelephoneDirectory</p><p> number文本類型;電話號(hào)碼</p><p> subscriber文本類型;
59、電話用戶姓名</p><p> 表CallHistory</p><p> number文本類型;電話號(hào)碼(索引,允許重復(fù))</p><p> startTime日期/時(shí)間類型;起始通話時(shí)間</p><p> endTime日期/時(shí)間類型;終止通話時(shí)間</p><p> 圖1.1 話費(fèi)查詢程
60、序中的數(shù)據(jù)庫(kù)設(shè)計(jì)</p><p> 其中,表TelephoneDirectory記錄了所有用戶的電話號(hào)碼,以number為主關(guān)鍵碼;表CallHistory記錄了所有電話的通話歷史,其中number是外部關(guān)鍵碼,建立該屬性的允許重復(fù)的索引。表CallHistory通過(guò)外部關(guān)鍵碼number與表TelephoneDirectory相關(guān)聯(lián)。由于同一名字的用戶可能登記多個(gè)電話號(hào)碼(例如一個(gè)用戶同時(shí)擁有兩部住宅電話和一
61、部移動(dòng)電話),因而電話計(jì)費(fèi)查詢程序除了提供根據(jù)電話號(hào)碼查詢?cè)捹M(fèi)清單外,還可能提供以用戶名字進(jìn)行查詢。本例子程序演示了后者的用法。</p><p> 程序中利用JDBC/ODBC訪問(wèn)數(shù)據(jù)庫(kù),因而支持使用多種不同的數(shù)據(jù)庫(kù)管理系統(tǒng),只要這些數(shù)據(jù)庫(kù)管理系統(tǒng)提供了ODBC接口,如Microsoft Access、Microsoft SQL Server、Sybase、Oracle等。</p><p&g
62、t; 使用ODBC訪問(wèn)數(shù)據(jù)庫(kù)之前,必須將數(shù)據(jù)庫(kù)配置為ODBC的一個(gè)數(shù)據(jù)源。假設(shè)我們選用了Microsoft Access數(shù)據(jù)庫(kù),則這一安裝步驟為:在Windows 98的控制面板中打開“ODBC數(shù)據(jù)源(32位)”,單擊“添加”按鈕后選擇一個(gè)驅(qū)動(dòng)程序(此處應(yīng)為“Microsoft Access Driver (*.mdb)”),然后為數(shù)據(jù)源命名并選擇相關(guān)聯(lián)的Access數(shù)據(jù)庫(kù)文件,如圖1.2所示。</p><p>
63、; 圖1.2 在Windows 98中添加ODBC數(shù)據(jù)源</p><p> 為進(jìn)一步提高程序的數(shù)據(jù)獨(dú)立性,還可以利用許多關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)支持的“存儲(chǔ)過(guò)程”來(lái)完成數(shù)據(jù)查詢與更新操作。數(shù)據(jù)獨(dú)立性使得在數(shù)據(jù)庫(kù)中表的屬性或表之間的關(guān)聯(lián)發(fā)生某些變化時(shí),程序員無(wú)需對(duì)應(yīng)用程序作任何修改。使用存儲(chǔ)過(guò)程訪問(wèn)數(shù)據(jù)庫(kù)還可帶來(lái)其他好處,例如提高了SQL語(yǔ)句查詢與更新數(shù)據(jù)庫(kù)的效率,在網(wǎng)絡(luò)環(huán)境下加強(qiáng)了數(shù)據(jù)庫(kù)的安全性等等。在不同的數(shù)
64、據(jù)庫(kù)管理系統(tǒng)中,存儲(chǔ)過(guò)程可能有不同的名字,如保留過(guò)程、觸發(fā)器、查詢等。</p><p> 圖1.3展示了在Microsoft Access中編寫的一個(gè)存儲(chǔ)過(guò)程(即一個(gè)查詢),它根據(jù)指定電話用戶名字的參數(shù)(Telephone Subscriber)查詢?cè)撚脩舻怯浀乃须娫挼耐ㄔ捰涗洝1竟?jié)的例子程序利用該存儲(chǔ)過(guò)程實(shí)現(xiàn)對(duì)數(shù)據(jù)的查詢。</p><p> 查詢QueryCallHistoryWi
65、thSubscriber</p><p> SELECT TelephoneDirectory.number, CallHistory.startTime, CallHistory.endTime</p><p> FROM TelephoneDirectory, CallHistory</p><p> WHERE(TelephoneDirectory
66、.number = CallHistory.number) AND </p><p> (TelephoneDirectory.subscriber = [Telephone Subscriber])</p><p> ORDER BY startTime;</p><p> 圖1.3 根據(jù)用戶名字查詢通話記錄的存儲(chǔ)過(guò)程</p><
67、;p> 客戶程序與服務(wù)程序之間的通信</p><p> 客戶程序與服務(wù)程序之間需要通信以交換信息。在本小節(jié)的例子程序中,服務(wù)程序負(fù)責(zé)接收客戶程序發(fā)來(lái)的查詢請(qǐng)求,完成訪問(wèn)數(shù)據(jù)庫(kù)的查詢操作,并將查詢結(jié)果返回給客戶程序。客戶程序利用圖形用戶界面與終端用戶進(jìn)行交互,從終端用戶獲取電話用戶的名字并作為參數(shù)向服務(wù)程序發(fā)出查詢請(qǐng)求,然后將服務(wù)程序返回的查詢結(jié)果顯示給終端用戶瀏覽。</p><p&g
68、t; 客戶程序與服務(wù)程序可利用socket進(jìn)行通信,socket在TCP/IP網(wǎng)絡(luò)中是一種很原始、高效率的通信方式,但要求客戶程序與服務(wù)程序自己處理交換消息的編碼與解碼工作,即程序員必須自定義客戶程序與服務(wù)程序之間的應(yīng)用層通信協(xié)議,這不僅需要花費(fèi)大量的編程時(shí)間(例如必須考慮連接控制、錯(cuò)誤恢復(fù)、如何通過(guò)防火墻等問(wèn)題),同時(shí)也比較容易產(chǎn)生錯(cuò)誤。</p><p> 一種更好的通信方式是使用遠(yuǎn)程過(guò)程調(diào)用(RPC),它
69、將客戶程序與服務(wù)程序之間的通信接口抽象為過(guò)程調(diào)用層次,程序員可像調(diào)用本地過(guò)程一樣去調(diào)用遠(yuǎn)程過(guò)程,由RPC系統(tǒng)完成參數(shù)與返回值的打包、解包與傳輸?shù)鹊讓尤蝿?wù)。但使用RPC不能平滑地與面向?qū)ο蠹夹g(shù)結(jié)合在一起。</p><p> 本小節(jié)的例子程序采用了抽象層次更高的遠(yuǎn)程方法調(diào)用(RMI)。RMI是支持多層分布式對(duì)象計(jì)算的一系列Java類,使得Java應(yīng)用程序員無(wú)需額外的程序設(shè)計(jì)工作即可實(shí)現(xiàn)客戶程序與服務(wù)程序之間的連接與
70、通信,在客戶程序中可以像使用本地對(duì)象一樣調(diào)用服務(wù)程序中遠(yuǎn)程對(duì)象的方法。</p><p><b> 遠(yuǎn)程方法調(diào)用</b></p><p> RMI可看作一種簡(jiǎn)化的、專用于Java平臺(tái)的CORBA模型,由JDK 1.1開始支持。RMI的服務(wù)程序通常是一個(gè)Java應(yīng)用程序,而客戶程序既可以是一個(gè)Java應(yīng)用程序,也可以是一個(gè)Java Applet。</p>
71、<p> RMI注冊(cè)表rmiregistry是運(yùn)行在服務(wù)器上的一個(gè)后臺(tái)進(jìn)程,必須在服務(wù)程序啟動(dòng)之前就已啟動(dòng)完畢,它相當(dāng)于客戶程序與服務(wù)程序之間的通信網(wǎng)關(guān)。服務(wù)程序?qū)⑦h(yuǎn)程對(duì)象的名字注冊(cè)到RMI注冊(cè)表,客戶程序通過(guò)RMI注冊(cè)表將遠(yuǎn)程對(duì)象名字解析為遠(yuǎn)程對(duì)象引用,通過(guò)該對(duì)象引用調(diào)用遠(yuǎn)程對(duì)象上的方法。</p><p> RMI體系結(jié)構(gòu)采用典型的層次設(shè)計(jì)風(fēng)格,從上至下分別由樁/框架層、遠(yuǎn)程引用層和傳輸層組成,
72、各層之間明確定義了接口與協(xié)議,如圖1.4所示。</p><p> 應(yīng)用程序 客戶程序 服務(wù)程序</p><p> RMI系統(tǒng)樁 框 架</p><p><b> 遠(yuǎn) 程 引 用 層</b></p><p><b> 傳 輸 層</b></p>
73、<p> 圖1.4 遠(yuǎn)程方法調(diào)用(RMI)體系結(jié)構(gòu)</p><p> RMI系統(tǒng)采用類似CORBA的請(qǐng)求代理機(jī)制,樁(stub)是遠(yuǎn)程對(duì)象在客戶端的代理,客戶程序中的遠(yuǎn)程對(duì)象引用實(shí)際上是對(duì)本地樁的引用。樁負(fù)責(zé)將遠(yuǎn)程調(diào)用請(qǐng)求通過(guò)遠(yuǎn)程引用層轉(zhuǎn)發(fā)給服務(wù)端的框架(skeleton),再由服務(wù)端的框架分派給真正的遠(yuǎn)程對(duì)象實(shí)現(xiàn)。創(chuàng)建應(yīng)用程序時(shí),客戶程序與服務(wù)程序都需要樁,而框架僅服務(wù)程序需要。</p&
74、gt;<p> 遠(yuǎn)程引用層完成調(diào)用的語(yǔ)義,例如決定服務(wù)程序的對(duì)象是單個(gè)對(duì)象,還是需要與多個(gè)位置進(jìn)行通信的復(fù)制對(duì)象,這些語(yǔ)義由遠(yuǎn)程對(duì)象的實(shí)現(xiàn)提供。遠(yuǎn)程引用層還為上一層屏蔽了服務(wù)程序的激活方式,即樁/框架層不必關(guān)心提供遠(yuǎn)程對(duì)象的服務(wù)程序是一直在同一機(jī)器上運(yùn)行,還是僅在有方法調(diào)用時(shí)才被激活(JDK 1.2開始支持不同的激活策略)。</p><p> 傳輸層負(fù)責(zé)建立與管理連接,跟蹤遠(yuǎn)程對(duì)象,以及將調(diào)用請(qǐng)
75、求分派給合適對(duì)象。在服務(wù)端,傳輸層將調(diào)用請(qǐng)求向上轉(zhuǎn)發(fā)給遠(yuǎn)程引用層,遠(yuǎn)程引用層作相應(yīng)處理后轉(zhuǎn)發(fā)給框架,由框架向上調(diào)用遠(yuǎn)程對(duì)象的實(shí)現(xiàn),由遠(yuǎn)程對(duì)象的實(shí)現(xiàn)完成真正的方法調(diào)用。遠(yuǎn)程調(diào)用的返回值送回客戶端的路線是:首先經(jīng)過(guò)服務(wù)端的框架、遠(yuǎn)程引用層和傳輸層,再向上經(jīng)過(guò)客戶端的傳輸層、遠(yuǎn)程引用層和樁。</p><p> RMI在樁/框架層利用了兩種關(guān)鍵技術(shù)。首先,Java語(yǔ)言專用的對(duì)象串行化技術(shù)可將對(duì)象透明地傳送到不同地址空間
76、,樁與框架利用對(duì)象串行化技術(shù)打包(marshal)與解包(unmarshal)遠(yuǎn)程調(diào)用的參數(shù)與返回值。其次,動(dòng)態(tài)類裝載技術(shù)用于支持將客戶端的樁作為遠(yuǎn)程對(duì)象本身,樁實(shí)現(xiàn)了相同的遠(yuǎn)程接口集合,從而支持Java語(yǔ)言的類型檢查與類型轉(zhuǎn)換機(jī)制。</p><p><b> 接口定義</b></p><p> 一個(gè)基于RMI的多層模型分布式應(yīng)用程序通常包括以下幾部分:①遠(yuǎn)程接口
77、,規(guī)定了客戶程序與服務(wù)程序進(jìn)行交互的界面;②遠(yuǎn)程對(duì)象實(shí)現(xiàn),為遠(yuǎn)程接口規(guī)定的每一個(gè)方法提供真正的實(shí)現(xiàn);③服務(wù)程序,遠(yuǎn)程對(duì)象并不是服務(wù)程序本身,它需要由服務(wù)程序創(chuàng)建并注冊(cè),服務(wù)程序中的這些真正提供服務(wù)的對(duì)象實(shí)例又稱伺服對(duì)象(servant);④客戶程序,利用服務(wù)程序中伺服對(duì)象提供的服務(wù)完成某一功能。其中,遠(yuǎn)程接口是編寫服務(wù)程序與客戶程序之前需要首先考慮的問(wèn)題。</p><p> Java提供了接口與類兩種機(jī)制:接口
78、不含數(shù)據(jù)表示方法與操作的具體實(shí)現(xiàn),因而適用于定義對(duì)象的規(guī)格說(shuō)明(specification),一個(gè)接口可以同時(shí)繼承多個(gè)接口;類給出了數(shù)據(jù)表示方法與操作實(shí)現(xiàn),因而適用于定義對(duì)象的實(shí)現(xiàn)(implementation),僅支持對(duì)類的單繼承。所有遠(yuǎn)程對(duì)象的接口都使用接口來(lái)定義,并且必須繼承java.rmi.Remote接口,還要求其中的每一個(gè)方法必須聲明拋出java.rmi.RemoteException異常,因?yàn)榫W(wǎng)絡(luò)通信或服務(wù)程序等原因均可能
79、導(dǎo)致遠(yuǎn)程調(diào)用失敗。程序1-1給出了例子程序中通話記錄管理器的遠(yuǎn)程接口定義。</p><p> 程序1-1 CallManagerInterface.java</p><p> // 通話記錄管理器CallManager的遠(yuǎn)程接口</p><p> package Telephone;</p><p> public interfac
80、e CallManagerInterface</p><p> extends java.rmi.Remote</p><p><b> {</b></p><p> // 根據(jù)電話用戶名字查詢通話記錄。</p><p> // 參數(shù): subscriber - 電話用戶的名字</p><p&
81、gt; public Database.DatabaseTableModel getCallHistory(String subscriber)</p><p> throws java.rmi.RemoteException;</p><p><b> }</b></p><p><b> 服務(wù)端程序</b>&l
82、t;/p><p> 程序1-2定義的類CallManager為遠(yuǎn)程接口CallManagerInterface中的每一個(gè)遠(yuǎn)程方法提供了具體實(shí)現(xiàn)。為防止多個(gè)客戶程序并發(fā)地調(diào)用數(shù)據(jù)庫(kù)查詢操作,方法getCallHistory()被定義為同步方法。程序1-3所示ServerApplication是服務(wù)程序的主程序,它必須首先裝入安全管理器,用于保證動(dòng)態(tài)裝載的類不會(huì)執(zhí)行某些敏感操作,如果未指定安全管理器則不允許裝入任何RM
83、I類。</p><p> 程序1-2 CallManager.java</p><p> // 通話記錄管理器(即遠(yuǎn)程接口CallManagerInterface的實(shí)現(xiàn))</p><p> package Telephone;</p><p> public class CallManager</p><p>
84、; extends java.rmi.server.UnicastRemoteObject</p><p> implements CallManagerInterface</p><p><b> {</b></p><p><b> // 屬性定義</b></p><p> prote
85、cted Database.DatabaseAccess database;</p><p> // 缺省構(gòu)造方法,必須拋出RemoteException異常。</p><p> public CallManager()</p><p> throws java.rmi.RemoteException</p><p><b>
86、 {</b></p><p> database = new Database.DatabaseAccess();</p><p><b> }</b></p><p> // 根據(jù)電話用戶名字subscriber查詢通話記錄,實(shí)現(xiàn)遠(yuǎn)程接口指定的方法。</p><p> public synchro
87、nized Database.DatabaseTableModel getCallHistory(String subscriber)</p><p> throws java.rmi.RemoteException</p><p><b> {</b></p><p> String sql = "";
88、 // SQL查詢語(yǔ)句</p><p> Database.DatabaseTableModel table = null; // 返回的二維表模型</p><p> System.out.println("Respond to client request: " + subscriber);</p&g
89、t;<p><b> try {</b></p><p> sql = "QueryCallHistoryWithSubscriber('" + subscriber + "')";</p><p> java.sql.ResultSet rs = database.callQuery(sql
90、);</p><p> table = new Database.DatabaseTableModel(rs);</p><p> rs.close();</p><p> } catch(java.sql.SQLException exc) {</p><p> System.out.println(exc.getMessage()
91、);</p><p> System.exit(1);</p><p><b> }</b></p><p> return table;</p><p><b> }</b></p><p><b> }</b></p><
92、;p> 程序1-3 ServerApplication.java</p><p> // 服務(wù)程序的主程序</p><p> public class ServerApplication</p><p><b> {</b></p><p> final static String JDBC_DRIVE
93、R = "sun.jdbc.odbc.JdbcOdbcDriver";</p><p> public static void main(String args[])</p><p><b> {</b></p><p> // 為RMI設(shè)置安全管理器</p><p> System.setS
94、ecurityManager(new java.rmi.RMISecurityManager());</p><p> // 加載JDBC驅(qū)動(dòng)程序</p><p><b> try {</b></p><p> Class.forName(JDBC_DRIVER);</p><p> } catch(ClassN
95、otFoundException exc) {</p><p> System.out.println(exc.getMessage());</p><p> System.exit(1);</p><p><b> }</b></p><p> // 創(chuàng)建并注冊(cè)伺服對(duì)象</p><p>
96、<b> try {</b></p><p><b> // 創(chuàng)建伺服對(duì)象</b></p><p> Telephone.CallManager callManager = new Telephone.CallManager();</p><p> // 用名字"CallManagerServant001
97、"注冊(cè)伺服對(duì)象</p><p> java.rmi.Naming.rebind("CallManagerServant001", callManager);</p><p> } catch(java.rmi.RemoteException exc) {</p><p> System.out.println(exc.getMes
98、sage());</p><p> System.exit(1);</p><p> } catch(java.net.MalformedURLException exc) {</p><p> System.out.println(exc.getMessage());</p><p> System.exit(1);</p&g
99、t;<p><b> }</b></p><p> // 提示服務(wù)程序就緒</p><p> System.out.println("Call manager in the server is ready ...");</p><p><b> }</b></p>&
100、lt;p><b> }</b></p><p> 程序1-4定義的DatabaseAccess類與程序1-5定義的DatabaseTableModel類均用于抽象JDBC訪問(wèn)數(shù)據(jù)庫(kù)的行為,在實(shí)際應(yīng)用中我們通常會(huì)設(shè)計(jì)更完善、更個(gè)性化的數(shù)據(jù)庫(kù)訪問(wèn)程序包來(lái)包裝JDBC的API。DatabaseAccess主要用于管理服務(wù)程序與數(shù)據(jù)庫(kù)的連接,并完成數(shù)據(jù)庫(kù)的查詢與更新操作。DatabaseT
101、ableModel負(fù)責(zé)將數(shù)據(jù)庫(kù)查詢結(jié)果轉(zhuǎn)換為二維表數(shù)據(jù)模型的形式,方便利用Swing的二維表控件顯示查詢結(jié)果。在基于關(guān)系數(shù)據(jù)庫(kù)的應(yīng)用中,二維表控件是最常用的數(shù)據(jù)表達(dá)方式,對(duì)于某些具有層次結(jié)構(gòu)的數(shù)據(jù)則以樹控件表達(dá)會(huì)更加自然。</p><p> 程序1-4 DatabaseAccess.java</p><p> // 實(shí)現(xiàn)JDBC與數(shù)據(jù)庫(kù)的連接</p><p>
102、 package Database;</p><p> import java.sql.*;</p><p> public class DatabaseAccess</p><p><b> {</b></p><p><b> // 常量定義</b></p><p&
103、gt; protected final String DATABASE_NAME = "jdbc:odbc:Telephone";</p><p><b> // 屬性定義</b></p><p> protected Connection connection;// 為數(shù)據(jù)庫(kù)建立的連接</p><p> p
104、rotected Statement statement;// 將執(zhí)行的SQL語(yǔ)句</p><p> protected CallableStatement callable;// 將調(diào)用的SQL存儲(chǔ)過(guò)程語(yǔ)句</p><p><b> // 行為定義</b></p><p> // 構(gòu)造方法,建立與數(shù)據(jù)庫(kù)的連接。</p&
105、gt;<p> public DatabaseAccess()</p><p><b> {</b></p><p><b> try {</b></p><p> // 建立與指定數(shù)據(jù)庫(kù)的連接</p><p> connection = DriverManager.getC
106、onnection(DATABASE_NAME);</p><p> // 如果連接成功則檢測(cè)是否有警告信息</p><p> SQLWarning warn = connection.getWarnings();</p><p> while (warn != null) {</p><p> System.out.println(
107、warn.getMessage());</p><p> warn = warn.getNextWarning();</p><p><b> }</b></p><p> // 創(chuàng)建一個(gè)用于執(zhí)行SQL的語(yǔ)句</p><p> statement = connection.createStatement();&l
108、t;/p><p> callable = null;</p><p> } catch(SQLException exc) {</p><p> System.out.println(exc.getMessage());</p><p> System.exit(1);</p><p><b> }&l
109、t;/b></p><p><b> }</b></p><p> // 析構(gòu)方法,撤銷與數(shù)據(jù)庫(kù)的連接。</p><p> public synchronized void finalize()</p><p><b> {</b></p><p><b&
110、gt; try {</b></p><p> connection.close();</p><p> } catch(SQLException exc) {</p><p> System.out.println(exc.getMessage());</p><p> System.exit(1);</p>
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 軟件體系結(jié)構(gòu)設(shè)計(jì)案例分析
- 軟件體系結(jié)構(gòu)設(shè)計(jì)方法的研究
- VOIP系統(tǒng)中DSP的軟件體系結(jié)構(gòu)設(shè)計(jì).pdf
- 異構(gòu)軟件體系結(jié)構(gòu)設(shè)計(jì)方法研究.pdf
- 省級(jí)綜合結(jié)算系統(tǒng)體系結(jié)構(gòu)設(shè)計(jì)
- 智慧城市——事務(wù)模型軟件體系結(jié)構(gòu)設(shè)計(jì).pdf
- 集成體系結(jié)構(gòu)設(shè)計(jì)
- 分布式網(wǎng)絡(luò)管理體系結(jié)構(gòu)設(shè)計(jì)及性能、故障、安全管理模塊實(shí)現(xiàn).pdf
- 分布式應(yīng)用系統(tǒng)軟件體系結(jié)構(gòu)的研究與實(shí)踐.pdf
- 分布式溫度監(jiān)測(cè)軟件的設(shè)計(jì)【畢業(yè)設(shè)計(jì)】
- 省級(jí)綜合結(jié)算系統(tǒng)體系結(jié)構(gòu)設(shè)計(jì).pdf
- 軟件體系結(jié)構(gòu)設(shè)計(jì)方法的研究與應(yīng)用.pdf
- 分布式入侵檢測(cè)系統(tǒng)體系結(jié)構(gòu)的研究.pdf
- 分布式軟件體系結(jié)構(gòu)研究及在企業(yè)中應(yīng)用.pdf
- Manticore體系結(jié)構(gòu)設(shè)計(jì)——面向嵌入式系統(tǒng)的異構(gòu)多核處理器體系結(jié)構(gòu).pdf
- 面向智能噴霧機(jī)的軟件體系結(jié)構(gòu)設(shè)計(jì).pdf
- 課程設(shè)計(jì)報(bào)告-vpn體系結(jié)構(gòu)設(shè)計(jì)
- 體系結(jié)構(gòu)設(shè)計(jì)過(guò)程的研究.pdf
- 結(jié)構(gòu)設(shè)計(jì)畢業(yè)設(shè)計(jì)
- 建筑板柱結(jié)構(gòu)體系結(jié)構(gòu)設(shè)計(jì)新探
評(píng)論
0/150
提交評(píng)論