Java远程方法调用(二)
2007-12-23 12:25:37 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁绘劦鍓欓崝銈囩磽瀹ュ拑韬€殿喖顭烽幃銏ゅ礂鐏忔牗瀚介梺璇查叄濞佳勭珶婵犲伣锝夘敊閸撗咃紲闂佺粯鍔﹂崜娆撳礉閵堝洨纾界€广儱鎷戦煬顒傗偓娈垮枛椤兘骞冮姀銈呯閻忓繑鐗楃€氫粙姊虹拠鏌ュ弰婵炰匠鍕彾濠电姴浼i敐澶樻晩闁告挆鍜冪床闂備胶绮崝锕傚礈濞嗘挸绀夐柕鍫濇川绾剧晫鈧箍鍎遍幏鎴︾叕椤掑倵鍋撳▓鍨灈妞ゎ厾鍏橀獮鍐閵堝懐顦ч柣蹇撶箲閻楁鈧矮绮欏铏规嫚閺屻儱寮板┑鐐板尃閸曨厾褰炬繝鐢靛Т娴硷綁鏁愭径妯绘櫓闂佸憡鎸嗛崪鍐簥闂傚倷鑳剁划顖炲礉閿曞倸绀堟繛鍡樻尭缁€澶愭煏閸繃宸濈痪鍓ф櫕閳ь剙绠嶉崕閬嶅箯閹达妇鍙曟い鎺戝€甸崑鎾斥枔閸喗鐏堝銈庡幘閸忔﹢鐛崘顔碱潊闁靛牆鎳愰ˇ褔鏌h箛鎾剁闁绘顨堥埀顒佺煯缁瑥顫忛搹瑙勫珰闁哄被鍎卞鏉库攽閻愭澘灏冮柛鏇ㄥ幘瑜扮偓绻濋悽闈浶㈠ù纭风秮閺佹劖寰勫Ο缁樻珦闂備礁鎲¢幐鍡涘椽閸愵亜绨ラ梻鍌氬€峰ù鍥敋閺嶎厼鍨傞幖娣妼缁€鍐煥濠靛棙顥滈柣锕備憾濮婂宕掑▎鎺戝帯濡炪們鍨归敃銈夊煝瀹ュ鍗抽柕蹇曞Х椤斿姊洪幖鐐插姶闁告挻鐟╅幃姗€骞庨懞銉у幐闂佸憡鍔戦崝搴㈡櫠閺囩姷纾奸柍褜鍓熷畷姗€鍩炴径鍝ョ泿闂傚⿴鍋勫ú銈吤归悜鍓垮洭鏁冮埀顒勬箒濠电姴锕ら悧蹇涙偩濞差亝鐓涢悘鐐额嚙婵″ジ鏌嶇憴鍕伌鐎规洖宕埢搴ょ疀閹惧妲楃紓鍌氬€搁崐鐑芥⒔瀹ュ绀夐幖杈剧到閸ㄦ繃銇勯弽顐粶濡楀懘姊洪崨濠冨闁搞劍澹嗙划濠氬箮閼恒儱鈧敻鏌ㄥ┑鍡欏嚬缂併劏妫勯湁闁绘ǹ宕甸悾鐑樻叏婵犲啯銇濇俊顐㈠暙閳藉鈻庨幇顓炩偓鐑芥⒑鐠囨彃顒㈤柣顓у櫍瀹曪繝骞庨懞銉ヤ粧濡炪倖娲嶉崑鎾垛偓瑙勬礀閻栧ジ銆佸Δ浣哥窞閻庯綆鍋呴悵顐⑩攽閻樻剚鍟忛柛锝庡灣瀵板﹪宕滆閸嬫挾绮☉妯绘悙缂佺姵鐓¢弻娑㈠Ψ椤旂厧顫╅梺钘夊暟閸犳牠寮婚敐澶婃闁圭ǹ瀛╅崰鎰版⒑閼姐倕鏋庣紓宥咃躬瀵鈽夐埗鈹惧亾閿曞倸绠f繝闈涙川娴滎亝淇婇悙顏勨偓銈夊礈濞嗘挻鍋嬮柛鈩冪▓閳ь剚妫冨畷姗€顢欓崲澹洤绠圭紒顔煎帨閸嬫捇鎳犻鈧崵顒傜磽閸屾艾鈧娆㈤敓鐘茬獥婵°倕鎳庣粻浼存煙闂傚鍔嶉柛瀣ф櫊閺岋綁骞嬮敐鍡╂缂佺虎鍘搁崑鎾绘⒒娴h櫣甯涢柛鏃€娲滅划鏃堟濞磋櫕鐩畷姗€顢欓崗鍏夹氶梻渚€鈧偛鑻晶顖炴煏閸パ冾伃妤犵偞甯¢獮瀣攽閹邦亞纾婚梺璇叉唉椤骞愭搴g焼濞撴埃鍋撻柛鈺冨仱楠炲鏁傞挊澶夋睏闂備礁婀辩划顖滄暜閳哄倸顕遍柍褜鍓涚槐鎾存媴閻熸澘濮㈤悷婊勫閸嬬喖宕氶幒鎴旀瀻闁规儳鐤囬幗鏇炩攽閻愭潙鐏﹂柣顓у枛閳讳粙顢旈崼鐔哄幍闁荤喐鐟ョ€氼剚鎱ㄩ崶銊d簻闁靛濡囩粻鐐存叏婵犲啯銇濋柡灞芥嚇閹瑩鎳犵捄渚純濠电姭鎷冮崒姘ギ闂佸搫鐬奸崰鏍箹瑜版帩鏁冮柨婵嗘噽閿涙捇姊绘担鐟邦嚋缂佽瀚板畷鎴濃槈閵忕姷鍘撮梺鐟邦嚟婵參宕戦幘缁樻櫜閹煎瓨锚娴滅偓銇勯幘瀵糕姇婵炲懎锕弻锛勪沪閻e睗锝嗙箾绾板彉閭鐐茬箳娴狅箓鎸婃径濠呭帿闂傚倸鍊烽悞锕傛儑瑜版帒纾归柡鍥ュ灩缁犵娀鏌熼柇锕€鏋熸い顐f礋閺岀喖骞嗚閹界姴鈹戦娑欏唉闁哄本鐩獮姗€寮堕幋鐘点偡闂備礁鎲¢幐绋跨暦椤掑嫧鈧棃宕橀鍢壯囨煕閳╁喚娈樺ù鐘虫倐濮婃椽鎳¢妶鍛瘣闂佸搫鎳忛惄顖炲箖妤e啯鍊婚柦妯猴級閵娧勫枑濠㈣埖鍔曠壕濠氭煙閸撗呭笡闁哄懏鐓¢獮鏍垝閻熸澘鈷夐梺璇茬箰缁夌懓顫忛搹鍦<婵☆垵顕ч棄宥呪攽閻愭彃绾ч柨鏇樺灪娣囧﹪鎮界粙璺槹濡炪倖鐗楀銊╂偪閳ь剟姊婚崒姘偓鎼佹偋婵犲嫮鐭欓柟閭﹀枦婵娊鏌ゅù瀣珖缁炬崘妫勯湁闁挎繂鐗婇ˉ澶愭煟閹炬潙濮堥柟渚垮妼铻g紒瀣仢椤鈹戦垾鍐茬骇闁告梹鐟╅悰顔嘉熼崗鐓庣彴闂佽偐鈷堥崜锕€危娴煎瓨鈷掑ù锝嚽归弳閬嶆煙绾板崬浜扮€规洘鍔栫换婵喰掔粙鎸庡枠鐎殿喛鍩栭幆鏃堝箻鐎涙ɑ婢戝┑锛勫亼閸婃牕顫忔繝姘ラ悗锝庝憾閸熷懘鏌曟径娑滅濞存粍绮嶉妵鍕箻鐠鸿桨绮跺┑鈩冨絻椤兘寮婚敐澶嬫櫜闁搞儜鍐ㄧ婵°倗濮烽崑鐐垫暜閿熺姷宓侀悗锝庡枛缁秹鏌嶈閸撶喖骞冨Δ浣虹瘈婵﹩鍘搁幏娲煟閻斿摜鎳冮悗姘煎弮瀹曟洖螖閸涱喚鍘卞┑鈽嗗灥閵嗏偓闁稿鎹囬幃銏ゅ箵閹烘垹闃€婵犵數濮烽弫鍛婃叏閻戣棄鏋侀柛娑橈攻閸欏繘鏌i幋锝嗩棄闁哄绶氶弻娑樷槈濮楀牊鏁鹃梺鍛婄懃缁绘垿濡甸崟顖氱闁告鍋熸禒鑲╃磼閻愵剙鍔ゆい顓犲厴瀵鎮㈤悡搴n槶閻熸粌绻掗弫顔尖槈閵忥紕鍘撻梻浣哥仢椤戝懘鎮橀敃鍌涚厪闁搞儜鍐句純濡ょ姷鍋炵敮鈥崇暦閸楃儐娓婚柟顖嗗本顥$紓鍌氬€搁崐鎼佸磹妞嬪海鐭嗗〒姘e亾閽樻繈姊洪鈧粔鎾几娴g硶鏀介柣妯挎珪閻ㄦ垹鈧鎸风欢姘跺蓟濞戙垹鐒洪柛鎰典簴婵洭姊虹粙鍖″姛闁稿繑锕㈠璇测槈濡攱鏂€闂佺硶鍓濋〃蹇斿閳ь剚淇婇悙顏勨偓鏍ь潖瑜版帒绀夐柡鍥ュ灩閻撴﹢鏌熸潏楣冩闁稿﹤顭烽弻娑㈠Ψ閵忊剝鐝栭柡宥忕節濮婄粯鎷呴崨濠傛殘闂佸湱枪椤兘骞冮悜鑺ユ櫆闁伙絽澶囬弨铏節閻㈤潧孝婵炶绠撳畷鐢稿礃椤旂晫鍘撻梺鍛婄箓鐎氼剟寮抽悢鍏肩叆婵炴垶鐟ч惌鎺撴叏婵犲洨绱伴柕鍥ㄥ姍楠炴帡骞嬪⿰鍐╃€抽梻鍌欑閹诧繝鎮烽妷锔绘闁归棿绀侀悡婵嬫煙閻愵剚鐏遍柛顐邯閺屾盯顢曢妶鍛亖闂佸憡蓱閹倿寮婚敐鍫㈢杸闁哄洨鍋橀幋椋庣磼缂併垹骞栭柣鏍帶閻g兘骞嬮敃鈧粻濠氭偣閸ヮ亜鐨洪柣銈傚亾婵犵數鍋犻幓顏嗗緤娴犲绠熼柨鐔哄Т绾捐銇勯弽顐沪闁抽攱鍨归惀顏堫敇閻愭潙娅f繛瀛樼矊缂嶅﹪骞冪捄琛℃闁哄诞鍐ㄐ曢梻浣虹《閺備線宕戦幘鎰佹富闁靛牆妫楃粭鎺楁煕閻曚礁浜伴柟顖氬暙鐓ゆい蹇撴噽閸樺憡绻涙潏鍓у埌婵犫偓鏉堛劍娅犳い蹇撶墛閻撳啴鎮峰▎蹇擃仼闁诲繑鎸抽弻鐔碱敊閻e本鍣伴悗娈垮枛閻栧ジ鐛€n喗鍋愰弶鍫厛閺佸洭姊婚崒姘偓椋庣矆娴i潻鑰块弶鍫涘妿娴犳岸姊绘担渚敯濠殿喓鍊楅崚鎺撴償閵娿儳顦梺鍦劋椤ㄥ懐鐚惧澶嬬厱妞ゆ劑鍊曢弸搴∶归悩鐑橆仩缂佽鲸鎸婚幏鍛村礈閹绘帒澹嶆俊鐐€栧ú妯荤箾婵犲洤鏋侀柛鎰靛枛绾惧吋绻涢幋鐐跺妤犵偛鐗撳缁樻媴閸涘﹥鍎撳┑鐐茬湴閸ㄨ棄鐣峰┑鍡欐殕闁告洦鍓欓埀顒€鐖奸弻锝呂熼懖鈺佺闂佺粯鎸诲ú鐔煎蓟閻斿吋鍤嬫い鎺嗗亾濠碉紕鍘ч湁婵犲﹤瀚崝銈夋煃鐟欏嫬鐏撮柡浣哥Ч瀹曠喖顢曢埄鍐╃窔闂傚倷鑳舵灙闁挎洏鍎甸幃褔鎮╅懠顒佹濠电娀娼ч鍡涘疾濠靛鐓冪憸婊堝礈閻旂厧鐏抽柨鏇炲€搁柨銈嗕繆閵堝倸浜鹃梺缁樺笒閻忔岸濡甸崟顖氱鐎广儱鐗嗛崢锛勭磽娴e搫孝濠⒀傜矙閸┾偓妞ゆ巻鍋撻柛妯荤矒瀹曟垿骞橀弬銉︽杸闂佺粯枪娴滎剛绮i弮鍫熺厱閻庯綆鍋掑▓鏃堟煃鐟欏嫬鐏存い銏$懅濞戠敻鎮滈悾灞藉冀濠电姷鏁搁崑娑㈠箯閹寸姴绶ら柛顭戝暎閿濆绠涢柡澶庢硶椤斿﹪姊洪悷鏉挎毐缁剧虎鍙冨畷浼村箻鐠囪尙顔嗛梺缁樶缚缁垶宕甸幋锔界厾缂佸娉曟禒娑欐叏閿濆棗濮嶆慨濠傤煼瀹曟帒顫濋钘変壕闁绘垼濮ら崵鍕煠閸濄儲鏆╁ù鐘崇缁绘繈鎮介棃娑楃捕濡炪倖娲﹂崣鍐ㄧ暦濡も偓铻e〒姘煎灠濞堛劌顪冮妶鍡楀闁稿﹥鐗滈埀顒佺濮樸劑鍩€椤掑倹鍤€濠㈢懓锕畷浼村冀瑜夐弸鏃堟煏婵犲繐顩紒鈾€鍋撻梻浣圭湽閸ㄨ棄岣胯閻楀海绱撴担鍝勪壕婵犮垺岣跨划鏃堟偡闁箑娈ㄩ梺鍝勮閸庤京绮婚悽鍛婄厵闁绘垶岣跨粻姗€鏌涢悙鍨毈闁哄矉缍侀幃鈺呮倻濮楀棔鍝楅梺璇茬箰缁诲牓宕濆畝鍕垫晩闊洦绋戝敮閻熸粌顦靛畷鎴﹀箻閼搁潧鏋傞梺鍛婃处閸撴瑧鍠婂鍛斀闁宠棄妫楁禍婵堢磼鐠囨彃鈧潡鏁愰悙鍓佺杸婵炴垶鐟﹂崕顏堟⒑闂堚晛鐦滈柛姗€绠栭弫宥呪堪閸愶絾鏂€闂佸疇妫勫Λ妤呮倶閻樼粯鐓欑痪鏉垮船娴滀即鏌ㄥ┑鍫濅粶妞ゆ挸銈稿畷鍫曞煛閸愯法闂繝鐢靛仩閹活亞绱炴笟鈧棢闁规崘顕х粈澶屸偓骞垮劚椤︿即鎮″▎鎴犵<閻庯綆浜炴禒銏ゆ煛閸℃稐鎲鹃柡宀嬬秮閺佹劙宕惰楠炲螖閻橀潧浠滄い鎴濐樀瀵偊宕橀鑲╁姦濡炪倖甯掗崐缁樼▔瀹ュ應鏀介柣妯虹-椤f煡鏌涚€e墎绉柡灞剧洴婵$兘骞嬪┑鍡樻婵°倗濮村ú顓㈠箖濡ゅ啯鍠嗛柛鏇ㄥ墮绾板秶绱撴担鍓叉Ч闁瑰憡濞婇崹楣冨籍閸繄顦ㄥ銈嗘煥濡插牐顦归柡灞剧洴閸╁嫰宕楅悪鈧禍顏勎涢崟顐悑闁搞儮鏅濋敍婵囩箾鏉堝墽鍒板鐟帮躬瀹曟洟骞囬悧鍫㈠幈闂侀潧枪閸庨亶銆傚畷鍥╃<妞ゆ梻鈷堥崕蹇斻亜閹惧啿鎮戠€垫澘瀚埀顒婄秵娴滄牠宕戦幘缁樼叆閻庯絻鍔嬬花濠氭⒑閻熺増鎯堢紒澶婄埣钘濋柨鏃堟暜閸嬫挸鈻撻崹顔界亪闂佽绻戠换鍫ュ春閻愬搫绠i柨鏇楀亾闁绘搫绻濋弻娑㈠焺閸愮偓鐣兼繛瀵稿閸ㄨ泛顫忓ú顏勫窛濠电姴娴烽崝鍫曟⒑閸涘﹥澶勯柛娆忛鐓ら柛娑橈梗缁诲棝鏌曢崼婵堢闁告帊鍗抽弻娑㈡偆娴e摜浠搁悗瑙勬礃閸旀瑥鐣疯ぐ鎺濇晝闁挎繂鎳庢导搴㈢節绾版ɑ顫婇柛銊﹀▕瀹曘垼顦崇紒鍌氱У閵堬綁宕橀埡浣插亾閸偅鍙忔俊顖滃帶娴滈箖鎮楀鐐

核心提示:出自:java爱好者传递属性前面我们讲到,RMI可以传递属性,Java远程方法调用(二),并简单介绍了一下一个有关开支报告程序的情况,下面我们将深入讨论如何设计这样的系统,这最后一种策略可使您像修改政策一样简单地修改开支报告的内容--当公司决定需要把餐费划分为早餐、午餐和晚餐项目,而且像上述修改政策一样简单地执行修改时
出自:java爱好者
传递属性
前面我们讲到,RMI可以传递属性,并简单介绍了一下一个有关开支报告程序的情况。下面我们将深入讨论如何设计这样的系统。这样介绍的目的是使您能够利用RMI的功能将属性从一个系统传递到另一个系统,并随心所欲地安排当前的计算地点,并便于将来的改变。下面的例子并未涉及真实世界可能发生的所有问题,但可帮助读者了解处理问题的方法。
服务器定义的策略
图1是可进行动态配置的开支报告系统的示意图。客户机向用户显示图形用户界面(GUI),用户填写开支报告。客户机程序使用RMI与服务器进行通信。服务器使用JDBC( Java关系数据库连接包)将开支报告存储在数据库中。至此,这看起来与其它多层次系统大同小异,但有一个重大区别-- RMI能下载属性。
假定公司关于开支报告的政策发生改变。例如,目前公司只要求对超过20美元的开支需开具发票。但到明天,公司认为这太宽松了,便决定除不超过20美元的餐费以外,任何开支均需开具发票。如果不能下载属性的话,那么在设计便于修改的系统时您可选择下列方法之一:
用客户端安装与政策有关的程序。政策改变时,必须更新包含此政策的所有客户端程序。您可在若干服务器上安装客户程序,并要求所有用户从这些服务器之一运行客户程序,从而减少问题。但这仍不能彻底解决问题-- 那些让程序运行好几天的用户就无法使程序更新,而总是会有一些用户为了方便而把软件复制到本地磁盘上。
您可要求服务器在每次向开支报告添加项目时检查政策。但这样就会在客户机和服务器之间产生大量数据流,并增加服务器的工作量。这还会使系统变得更加脆弱--网络故障会立即妨碍用户,而不仅仅是只在其呈交开支报告或启动新的报告时对其产生影响。同时,添加项目的速度也会变慢,因为这需要穿越整个网络往返一圈才能到达(不堪重负的)服务器。
您可在呈交报告时要求服务器对政策进行检查。这样就会使用户创建很多必须待批报告的错误项目,而不是立刻捕捉到第一个错误,从而使用户有机会停止制造错误。为避免浪费时间,用户需要立刻得到有关错误的反馈。
有了RMI,您就能以简单的方法调用程序从服务器得到属性,从而提供了一种灵活的方式,将计算任务从服务器卸载到客户机上,同时为用户提供速度更快的反馈。当用户准备编写一份新的开支报告时,客户机就会向服务器要求一个对象,该对象嵌入了适用于该开支报告的当前政策,就如同通过用Java编写的政策接口所表示的那样。该对象可以以任何方式实现当前政策。如果这是客户机RMI首次看到这种专门执行的政策,就会要求服务器提供一份执行过程的副本。如果执行过程将来发生变化,则一种新的政策对象将被返回给客户机,而RMI运行时则会要求得到新的执行过程。
这表明,政策永远是动态的。您要想修改政策,就只需简单地编写通用政策接口的新的执行程序,把它安装在服务器上,并对服务器进行配置以返回这种新类型的对象即可。这样,每台客户机都会根据新的政策对新的开支报告进行检查。
这是一种比任何静态方法都更好的方法,原因如下:
所有客户机不必暂停或用新的软件来升级--软件可根据需要在不工作时加以更新。
服务器不必参与项目检查工作,该工作可在本地完成。
允许动态限制,因为对象执行程序(而不仅仅是数据)是在客户机和服务器之间进行传递的。
使用户能立刻看到错误。
使客户机在服务器上所能调用的方法的远程接口定义如下:
import java.rmi.*;
public interface EXPenseServer extends Remote {
Policy getPolicy() throws RemoteException;
void submitReport(ExpenseReport report)
throws RemoteException, InvalidReportException;
}
import语句输入Java RMI包。所有RMI类型均在包java.rmi或其子包内定义。接口ExpenseServer是一般的Java接口,具有如下两种有趣的特点:
它扩展了名为Remote的RMI接口,这使该接口标记为可用于远程调用。
它的所有方法均抛出RemoteException,后者用来表示网络或信息故障。
远程方法还可抛出您所需要的任何其他例外,但至少必须抛出RemoteException,这样您才能处理只会在分布式系统中发生的错误状态。该接口本身支持两个方法:getPolicy (返回一个实现政策接口的对象),和submitReport (提交一个完成的开支请求,并在报告无论因何种原因使表格出现错误时,抛出一个例外)。
政策接口本身可声明一种使客户机知道能否在开支报告中添加一个项目的方法:
public interface Policy {
void checkValid (Expenseentry entry)
throws PolicyViolationException;
}
如果该项目有效--即符合当前政策,则该方法可正常返回。否则就会抛出一个描述该错误的例外。政策接口是本地的(而非远程的),所以将通过本机对象在客户机上执行--在客户机的虚拟机上,而非整个网络上运行的对象。客户机可能运行下列程序:
Policy curPolicy = server.getPolicy();
start a new expense report
show the GUI to the user
while (user keeps adding entries) {
try {
curPolicy.checkValid(entry); // throws exception if not OK
add the entry to the expense report
} catch (PolicyViolationException e) {
show the error to the user
}
}
server.submitReport(report);
当用户请求客户机软件启动一份新的开支报告时,客户机就调用server.getPolicy,并要求服务器返回一个包含当前开支政策的对象。
添加的每个项目首先都被提交给该政策对象,以获得批准。如果政策对象报告无错误,则该项目就被添加到报告中;否则错误就被显示给用户,而后者可采取修正措施。当用户完成向报告中添加项目时,整个报告就被呈交。服务程序如下:
import java.rmi. *;
import java.rmi.server. *;
class ExpenseServerImpl
extends UnicastRemoteObject
implements ExpenseServer
{
ExpenseServerImpl() throws RemoteException {
// . . . set up server state . . .
}
public Policy getPolicy() {
return new TodaysPolicy();
}
public void submitReport(ExpenseReport report) {
// . . . write the report into the db . . .
}
}
除基本程序包外,我们还输入RMI的服务程序包。类型UnicastRemoteObject 定义了此服务程序远程对象的类型,在本例中,应为单一服务程序而非复制服务(下面还会详细介绍)。Java类ExpenseSeverImpl实现远程接ExpenseServer的方法。远程主机的客户机可使用RMI将信息发送给ExpenseServerImpl对象。
本文中讨论的重要方法是getPolicy,它简单地返回定义当前政策的对象。下面看一个执行政策的例子:
public class TodaysPolicy implements Policy {
public void checkValid(ExpenseEntry entry)
throws PolicyViolationException
{
if (entry.dollars() < 20) {
return; // no receipt required
else if (entry.haveReceipt() == false) {
throw new PolicyViolationException;
}
}
}
TodaysPolicy进行检查的目的是确保无收据的任何项目均少于20美元。如果将来政策发生变化,仅少于20美元的餐费可不受“需要收据”政策的限制,则您可提供新的政策实现:
public class TomorrowsPolicy implements Policy {
public void checkValid(ExpenseEntry entry)
throws PolicyViolationException
{
if (entry.isMeal() && entry.dollars() < 20) {
return; // no receipt required
} else if (entry.haveReceipt() == false) {
throw new PolicyViolationException;
}
}
}
编写这个类,并把它安装在服务器上,然后告诉服务器开始提供TomorrowsPolicy对象,而非daysPolicy对象,这样您的整个系统就会开始使用新的政策。当客户机调用服务器的getPolicy方法时,客户机的RMI就会检查返回的对象是否为已知类型。每台客户机首次遇到TomorrowsPolicy时,RMI就会在getPolicy返回前下载政策的实现。客户机可轻松地开始增强这个新的政策。
RMI使用标准Java对象序列化机制传递对象。引用远程对象参数作为远程引用传递。如果向某方法提供的参数为原始类型或本机(非远程)对象,则向服务器传递一个深副本。返回值也拾?照同样的方式处理,只不过是沿其它方向。RMI可使用户向本机对象传递和返回完整对象图并为远程对象传递和返回引用。
在真实的系统中,getPolicy方法可能会有一个可以识别用户及开支报告类型(差旅、客户关系等)的参数,这样可使政策加以区别。您或者可以不要求单独的政策和开支报告对象,但您可以有一种newExpenseReport方法,它可返回一个直接检查政策的ExpenseReport对象。这最后一种策略可使您像修改政策一样简单地修改开支报告的内容--当公司决定需要把餐费划分为早餐、午餐和晚餐项目,而且像上述修改政策一样简单地执行修改时--可编写一个实现该报告的新类,客户程序就会自动使用这个类。
(出处:http://www.cncms.com)
赞助商链接