代理模式簡(jiǎn)要介紹_第1頁
代理模式簡(jiǎn)要介紹_第2頁
代理模式簡(jiǎn)要介紹_第3頁
代理模式簡(jiǎn)要介紹_第4頁
代理模式簡(jiǎn)要介紹_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、描述:讓我們思考一下下面的代碼:    /Client 1. class Customer  2.   public void someMethod()  3.     /Create the Service Provider Instance  4.     FileUtil futilObj=new FileUtil();&

2、#160; 5.     /Access the Service  6.     futilObj.writeToFile(“Some Data”);  7.     8.           作為它實(shí)現(xiàn)的一部分,Customer類創(chuàng)建了一個(gè)FileUtil類的一個(gè)實(shí)例并且直接訪問它的服務(wù)。換句話說,對(duì)于客戶對(duì)象,訪問FileUtil對(duì)象的方式是很

3、直接的。它的實(shí)現(xiàn)可能是客戶對(duì)象訪問服務(wù)提供者對(duì)象最為普通的方式了。相比較,有些時(shí)候客戶對(duì)象可能不直接訪問服務(wù)提供者(也就是指目標(biāo)對(duì)象),這種情況是由于下面的原因?qū)е碌模海?)    目標(biāo)對(duì)象的位置?目標(biāo)對(duì)象可能存在于同一臺(tái)或者不同機(jī)器的不同地址空間。(2)    目標(biāo)對(duì)象的存在形式?目標(biāo)對(duì)象可能直到他被請(qǐng)求服務(wù)的時(shí)候還不存在,或者對(duì)象被壓縮。(3)    特殊的行為?目標(biāo)對(duì)象可以根據(jù)客戶對(duì)象的訪問權(quán)限接受或拒絕服務(wù)。在多線程環(huán)境,一些服務(wù)提供者對(duì)象需要特殊的考慮。 

4、   在這些情況下,代理模式(Proxy Pattern)建議不要使有特殊需求的客戶對(duì)象直接訪問目標(biāo)對(duì)象,而是使用一個(gè)單獨(dú)的(分離的)對(duì)象(也就是指代理對(duì)象)為不同的客戶提供通常的、直接的訪問目標(biāo)對(duì)象的方式。    代理對(duì)象提供和目標(biāo)對(duì)象一樣的接口。代理對(duì)象負(fù)責(zé)與目標(biāo)對(duì)象交互的細(xì)節(jié),代表客戶對(duì)象與目標(biāo)對(duì)象交互。所以客戶對(duì)象不再需要處理訪問目標(biāo)對(duì)象的服務(wù)時(shí)的特殊需求??蛻魧?duì)象通過它的接口調(diào)用代理對(duì)象,代理對(duì)象直接把這些調(diào)用依次地傳遞給目標(biāo)對(duì)象??蛻魧?duì)象不需要知道代理的原對(duì)象(目標(biāo)對(duì)象)。代理對(duì)象隱藏了與客戶對(duì)象進(jìn)行交

5、互的對(duì)象細(xì)節(jié),如:對(duì)象是否是遠(yuǎn)程的、是否初始化、是否需要特殊的權(quán)限等。換句話說,代理對(duì)象作為客戶和不可訪問的遠(yuǎn)程對(duì)象或推遲初始化對(duì)象之間的透明橋梁。   代理對(duì)象因使用的場(chǎng)景不同,代理的種類也不同。讓我們來快速的瀏覽一下一些代理和它們的目標(biāo)。注意:表23.1列出了不同種類的代理對(duì)象,在一章中,僅討論遠(yuǎn)程代理,其他的一些代理會(huì)在本書后面的模式中討論。Table 23.1: List of Different Proxy Types 代理類型     

6、;目的 遠(yuǎn)程代理    提供對(duì)在不同地址空間的遠(yuǎn)程對(duì)象的訪問緩存代理/服務(wù)代理    為了提供能夠保存目標(biāo)操作經(jīng)常用到的結(jié)果,代理對(duì)象以存儲(chǔ)方式保存這些結(jié)果。當(dāng)客戶對(duì)象請(qǐng)求同一個(gè)操作時(shí),代理不需要直接訪問目標(biāo)對(duì)象,而是從存貯介質(zhì)返回操作結(jié)果。防火墻代理    使用防火墻代理主要是為了保護(hù)目標(biāo)對(duì)象以防止有害客戶的訪問。同時(shí)也可以防止客戶訪問有害的目標(biāo)對(duì)象。保護(hù)代理    提供了不同客戶訪問不同層次的目標(biāo)對(duì)象的功能。在創(chuàng)建代理時(shí),

7、定義了一個(gè)權(quán)限的集合。雖后,這些權(quán)限用來限制訪問代理的特定部分,如果沒有執(zhí)行方法的權(quán)限,客戶對(duì)象不允許訪問特定的方法。同步代理    提供了允許不同的客戶對(duì)象安全的同步訪問目標(biāo)對(duì)象的功能。計(jì)數(shù)代理    在執(zhí)行目標(biāo)對(duì)象的方法前,提供了一些審計(jì)機(jī)制。代理模式和其他模式從討論不同的代理對(duì)象中可以看出:代理對(duì)象有兩個(gè)主要的特征:(1)    它介于客戶對(duì)象和目標(biāo)對(duì)象之間。(2)    它接受客戶對(duì)象的調(diào)用,然后轉(zhuǎn)發(fā)調(diào)用給目標(biāo)對(duì)象。在這種情形下

8、,看上去和本書中前面討論的其他模式有些相似。讓我們討論一下代理模式和一些與它相似的模式之間的相同點(diǎn)和不同點(diǎn)。代理模式和裝飾模式:代理模式:(1)    客戶對(duì)象不能直接訪問目標(biāo)對(duì)象(2)    代理對(duì)象提供了對(duì)目標(biāo)對(duì)象的訪問控制(在保護(hù)代理中)(3)    代理對(duì)象不能再增加其他的功能。裝飾模式:(1)    如果需要,客戶對(duì)象不能直接訪問目標(biāo)對(duì)象。(2)    裝飾對(duì)象不能控制對(duì)目標(biāo)對(duì)象的訪問。

9、(3)    裝飾對(duì)象可以增加額外的功能。代理模式和外觀模式:代理模式:(1)    代理對(duì)象代表一個(gè)單一對(duì)象。(2)    客戶對(duì)象不能直接訪問目標(biāo)對(duì)象。(3)    代理對(duì)象提供了對(duì)于單一目標(biāo)對(duì)象的訪問控制。外觀模式:(1)    外觀對(duì)象代表了對(duì)象的一個(gè)子系統(tǒng)。(2)    如果必要,客戶對(duì)象可以直接訪問子系統(tǒng)中的對(duì)象。(3)  &

10、#160; 一個(gè)外觀對(duì)象提供了一個(gè)對(duì)子系統(tǒng)組件的簡(jiǎn)單的、高層次的接口.代理模式和責(zé)任鏈模式:代理模式:(1)    代理對(duì)象代表了一個(gè)單一的對(duì)象。(2)    克輝請(qǐng)求首先被代理對(duì)象所接受,但是不直接被代理對(duì)象處理。(3)    客戶請(qǐng)求總是被傳遞給目標(biāo)對(duì)象。(4)    假設(shè)客戶與服務(wù)器正常工作,可以保證請(qǐng)求會(huì)得到響應(yīng),責(zé)任鏈模式:(1)    責(zé)任鏈包括很多對(duì)象。(2) &

11、#160;  接受客戶請(qǐng)求的對(duì)象首先處理請(qǐng)求。(3)    近當(dāng)現(xiàn)在的接收者不能處理請(qǐng)求時(shí),客戶請(qǐng)求才被傳遞給下一個(gè)對(duì)象。(4)    不能保證請(qǐng)求會(huì)得到響應(yīng)。也就是請(qǐng)求已經(jīng)到達(dá)責(zé)任鏈尾,擔(dān)仍然沒有被處理。在Java中,遠(yuǎn)程方法調(diào)用(RMI)充分的利用了遠(yuǎn)程代理模式,讓我們快速的瀏覽一下遠(yuǎn)程方法調(diào)用(RMI)的概念和遠(yuǎn)程方法調(diào)用(RMI)通信過程應(yīng)用的組件。RMI:快速瀏覽RMI使客戶對(duì)象像訪問本地對(duì)象一樣訪問遠(yuǎn)程對(duì)象并調(diào)用其方法成為可能。(如圖23.1) Figure 23

12、.1: Clients View of Its Communication with a Remote Object Using RMI 下面是為實(shí)現(xiàn)RMI功能而一起協(xié)作的不同組件。(1)    遠(yuǎn)程接口(Remote Interface)?一個(gè)遠(yuǎn)程對(duì)象必須實(shí)現(xiàn)一個(gè)遠(yuǎn)程接口(這個(gè)接口擴(kuò)展java.rmi.Remote)。遠(yuǎn)程接口聲明可以被客戶訪問的遠(yuǎn)程對(duì)象的方法。換句話說,遠(yuǎn)程接口可以看成遠(yuǎn)程對(duì)象對(duì)客戶的視圖。需求(要求):1

13、)    擴(kuò)展java.rmi.Remote2)    在遠(yuǎn)程接口中定義的所有方法必須聲明拋出java.rmi.RemoteException異常。(2)    遠(yuǎn)程對(duì)象(Remote Object)?遠(yuǎn)程對(duì)象負(fù)責(zé)實(shí)現(xiàn)在遠(yuǎn)程接口中定義的方法。需求(要求):1)    必須提供遠(yuǎn)程接口的實(shí)現(xiàn)。2)    必須擴(kuò)展java.rmi.server.UnicastRemoteObject類。3)

14、    必須有一個(gè)沒有參數(shù)的構(gòu)造函數(shù)。4)    必須與一個(gè)服務(wù)器相關(guān)聯(lián)。通過調(diào)用零參數(shù)的構(gòu)造函數(shù),服務(wù)器創(chuàng)建遠(yuǎn)程對(duì)象的一個(gè)實(shí)例。(3)    RMI注冊(cè)表(RMI Registry)?RMI注冊(cè)表提供了保持不同遠(yuǎn)程對(duì)象的地址空間。1)    遠(yuǎn)程對(duì)象需要存儲(chǔ)在一個(gè)客戶可以通過命名引用(Name reference)來訪問它的RMI注冊(cè)表中。2)    一個(gè)給定的命名引用僅可以

15、存儲(chǔ)一個(gè)對(duì)象。(4)    客戶(Client)?客戶是一個(gè)試圖訪問遠(yuǎn)程對(duì)象的應(yīng)用程序。1)    必須可以感知被遠(yuǎn)程對(duì)象實(shí)現(xiàn)的接口。2)    通過命名引用(Name reference)在RMI注冊(cè)表中可以查到遠(yuǎn)程對(duì)象。一旦查到遠(yuǎn)程對(duì)象的引用,調(diào)用這個(gè)引用上的方法。(5)RMIC (Java RMI 樁編譯器)Java RMI stub compiler?一旦遠(yuǎn)程對(duì)象編譯成功,RMIC(Java

16、0;RMI 樁編譯器)可以生成遠(yuǎn)程對(duì)象的樁類文件(stub)和框架類文件(skeleton)。樁類文件(stub)和框架類文件(skeleton)從編譯的遠(yuǎn)程對(duì)象類中產(chǎn)生。這些樁類文件(stub)和框架類文件(skeleton) 使客戶對(duì)象以無縫的方式訪問遠(yuǎn)程對(duì)象成為可能。下面這部分描述客戶對(duì)象和遠(yuǎn)程對(duì)象如何通信。RMI通信機(jī)制:    一般地,客戶對(duì)象不能按通常方式直接訪問遠(yuǎn)程對(duì)象。為了使客戶對(duì)象像訪問本地對(duì)象一樣訪問遠(yuǎn)程對(duì)象的服務(wù),RMIC(Java RMI 樁編譯器)生成的遠(yuǎn)程對(duì)象的樁文件(stub)和遠(yuǎn)程接

17、口需要拷貝到客戶機(jī)器上。    樁文件(stub)負(fù)責(zé)扮演著遠(yuǎn)程對(duì)象的(遠(yuǎn)程)代理的角色,負(fù)責(zé)把方法的調(diào)用傳遞給真實(shí)的遠(yuǎn)程對(duì)象實(shí)現(xiàn)所在的遠(yuǎn)程服務(wù)器上。任何時(shí)候,客戶對(duì)象引用遠(yuǎn)程對(duì)象,這個(gè)引用實(shí)際上是遠(yuǎn)程對(duì)象的本地樁文件。也就是,當(dāng)客戶調(diào)用遠(yuǎn)程對(duì)象上的方法時(shí),調(diào)用首先被本地樁實(shí)例所接受,樁再將這個(gè)調(diào)用傳遞到遠(yuǎn)程服務(wù)器上。在服務(wù)器端,RMIC產(chǎn)生的遠(yuǎn)程對(duì)象的框架文件(skeleton)接受這個(gè)調(diào)用。    框架文件(skeleton)在服務(wù)器端,不需要拷貝到客戶機(jī)器上??蚣芪募?skeleton)負(fù)責(zé)將這些調(diào)用轉(zhuǎn)發(fā)到真

18、正的遠(yuǎn)程對(duì)象的實(shí)現(xiàn)上。一旦遠(yuǎn)程對(duì)象執(zhí)行了方法,方法返回的結(jié)果將按照反方向返回給客戶。    圖23.2說明了RMI通信的過程 Figure 23.2: The Actual RMI Communication Process 了解更多的關(guān)于Java RMI的知識(shí),推薦閱讀RMI tutorialRMI和遠(yuǎn)程代理模式:    從RMI通信的討論中,可以看到樁類文件扮演著遠(yuǎn)程對(duì)象的遠(yuǎn)程代理的角色。它使得客戶訪問遠(yuǎn)程對(duì)象就

19、像訪問本地對(duì)象一樣成為可能。因此,一些使用了RMI技術(shù)的應(yīng)用就已經(jīng)暗含著代理模式的實(shí)現(xiàn)。例子:    在討論外觀模式時(shí),我們建立了一個(gè)簡(jiǎn)單的客戶數(shù)據(jù)管理應(yīng)用來驗(yàn)證和保存輸入的客戶數(shù)據(jù)。我們的設(shè)計(jì)由分別代表不同客戶數(shù)據(jù)的三個(gè)類組成。在應(yīng)用外觀模式以前,客戶AccountManager可以直接與子系統(tǒng)的三個(gè)用來驗(yàn)證、保存客戶數(shù)據(jù)的類交互。應(yīng)用外觀模式,我們定義了一個(gè)CustomFacade外觀對(duì)象代表客戶與三個(gè)子系統(tǒng)類交互(如圖23.3)。 Figure 23.3: Customer Data Managem

20、ent Application for the Local Mode of Operation?Class Association 在這個(gè)應(yīng)用中,子系統(tǒng)組件和外觀對(duì)象對(duì)于客戶對(duì)象AccountManager都是本地的?,F(xiàn)在,讓我們建立這個(gè)應(yīng)用的不同版本,這個(gè)版本已遠(yuǎn)程的方式運(yùn)行。在遠(yuǎn)程方式下,這個(gè)應(yīng)用通過運(yùn)用JAVA RMI技術(shù),訪問遠(yuǎn)程對(duì)象。在使應(yīng)用運(yùn)行在遠(yuǎn)程操作模式下的設(shè)計(jì)中,我們要把子系統(tǒng)組件(Account、Address和CreditCard)和外觀(CustomerFacade)移到

21、遠(yuǎn)程服務(wù)器上。這樣會(huì)帶來以下好處:1)    在服務(wù)器上的對(duì)象可以被不同的客戶應(yīng)用所共享??蛻舨辉傩枰S護(hù)這些類的本地版本,因此,成為輕型客戶端(light-weighted)。2)    可以對(duì)變化、性能和監(jiān)控進(jìn)行統(tǒng)一的集中控制。 Figure 23.4: Customer Data Management Application for the Remote Mode of Operation?

22、Class Association     讓我們開始運(yùn)用RMI技術(shù)設(shè)計(jì)遠(yuǎn)程操作模式下的客戶數(shù)據(jù)管理應(yīng)用。第一步,先定義遠(yuǎn)程接口CustomerIntr:這個(gè)借口要滿足:1)    聲明外觀實(shí)現(xiàn)的方法。2)    所有的方法聲明拋出RemoteException異常。3)    擴(kuò)展java.rmi.Remote接口。1. public interface CustomerIntr ex

23、tends java.rmi.   2.   void setAddress( inAddress) throws RemoteException;  3.   void setCity( inCity) throws RemoteException;  4.   void setState( inState) throws RemoteException; 

24、; 5.   void setFName( inFName) throws RemoteException;  6.   void setLName( inLName) throws RemoteException;  7.   void setCardType( inCardType) throws RemoteException;  8.   void 

25、setCardNumber( inCardNumber)  9.     throws RemoteException;  10.   void setCardExpDate( inCardExpDate)  11.     throws RemoteException;  12.   boolean saveCustomerData() throws Re

26、moteException;  13.       讓我們重新定義CustomerFacade外觀類,因?yàn)樗獙?shí)現(xiàn)CustomerIntr遠(yuǎn)程接口。不同的客戶對(duì)象通過CustomerIntr接口在具體類CustomerFacade上的實(shí)現(xiàn)與子系統(tǒng)對(duì)象進(jìn)行交互。圖23.5展示了CustomerFacade和它實(shí)現(xiàn)的遠(yuǎn)程接口CustomerIntr之間的結(jié)構(gòu)和關(guān)聯(lián)。Listing 23.1: CustomerFacade Class?Revised 1. public class 

27、;CustomerFacade extends UnicastRemoteObject  2.   implements CustomerIntr   3.   private  address;  4.   private  city;  5.   private  state;  6.   private  cardType

28、;  7.   private  cardNumber;  8.   private  cardExpDate;  9.   private  fname;  10.   private  lname;  11.   public CustomerFacade() throws RemoteException   12

29、.     super();  13.     .out.println("Server object created");  14.     15.   public static void main(  args) throws    16.      port =

30、 "1099"  17.      host = "localhost"  18.     /Check for hostname argument  19.     if (args.length = 1)   20.      

31、0;host = args0;  21.       22.     if (args.length = 2)   23.       port = args1;  24.       25.     if (.getSecurityMan

32、ager() = null)   26.       .setSecurityManager(new RMISecurityManager();  27.       28.     /Create an instance of the server  29.     CustomerFa

33、cade facade = new CustomerFacade();  30.     /Bind it with the RMI Registry  31.     Naming.bind("/" + host + ":" + port + "/CustomerFacade”

34、,  32.                 facade);  33.     .out.println("Service Bound");  34.     35.   public void setAddress( inAddress)  36

35、.     throws RemoteException   37.     address = inAddress;  38.     39.   public void setCity( inCity)  40.     throws RemoteException city = in

36、City;  41.     42.   public void setState( inState)  43.     throws RemoteException state = inState;  44.     45.   public void setFName( inFName)  46.  &#

37、160;  throws RemoteException fname = inFName;  47.     48.   public void setLName( inLName)  49.     throws RemoteException lname = inLName;  50.     51.  

38、 public void setCardType( inCardType)  52.     throws RemoteException   53.     cardType = inCardType;  54.     55.   public void setCardNumber( inCardNumber) 

39、56.     throws RemoteException   57.     cardNumber = inCardNumber;  58.     59.   public void setCardExpDate( inCardExpDate)  60.     throws RemoteException

40、60;  61.     cardExpDate = inCardExpDate;  62.     63.   public boolean saveCustomerData() throws RemoteException  64.     Address objAddress;  65.     Account&

41、#160;objAccount;  66.     CreditCard objCreditCard;  67.     /*  68.      client is transparent from the following  69.      set of subsystem rel

42、ated operations.  70.     */  71.     boolean validData = true;  72.      errorMessage = ""  73.     objAccount = new Account(fname, ln

43、ame);  74.     if (objAccount.isValid() = false)   75.       validData = false;  76.       errorMessage = "Invalid FirstName/LastName"  77.  

44、;     78.     objAddress = new Address(address, city, state);  79.     if (objAddress.isValid() = false)   80.       validData = false;  81.

45、       errorMessage = "Invalid Address/City/State"  82.       83.     objCreditCard = new CreditCard(cardType, cardNumber,  84.        

46、             cardExpDate);  85.     if (objCreditCard.isValid() = false)   86.       validData = false;  87.      &

47、#160;errorMessage = "Invalid CreditCard Info"  88.       89.     if (!validData)   90.       .out.println(errorMessage);  91.       return&#

48、160;false;  92.       93.     if (objAddress.save() && objAccount.save() &&  94.         objCreditCard.save()   95.       return&

49、#160;true;  96.       else   97.       return false;  98.       99.     100.    Figure 23.5: Façade Design?Remote Mode of Operatio

50、n     因?yàn)樽酉到y(tǒng)組件對(duì)于CustomerFacade類是本地的,子系統(tǒng)組件初始化、方法調(diào)用的方式上沒有任何變化,子系統(tǒng)組件對(duì)于CustomerFacade類仍然是本地對(duì)象。當(dāng)執(zhí)行的時(shí)候,CustomerFacade自己創(chuàng)建一個(gè)實(shí)例并把引用名稱(reference name)保存在RMI注冊(cè)表中。客戶對(duì)象通過引用名稱能取得遠(yuǎn)程對(duì)象的一個(gè)拷貝。    因?yàn)榭蛻舨恍枰苯釉L問任何的子系統(tǒng)組件。所以在遠(yuǎn)程操作模式下的設(shè)計(jì)中,不需要對(duì)子系統(tǒng)的任何組件進(jìn)行任何的修改。讓我們重新設(shè)計(jì)客戶類Account

51、Manager:Listing 23.2: AccountManager Class?Revised   1.          2.           3. public void actionPerformed(ActionEvent e)   4.       

52、    5.           6.   if (e.getActionCommand().equals(  7.         AccountManager.VALIDATE_SAVE)   8.     /get input values  9.  &

53、#160;   firstName = objAccountManager.getFirstName();  10.      lastName = objAccountManager.getLastName();  11.      address = objAccountManager.getAddress();  12.     &

54、#160;      13.            14.     try   15.       /Call registry for AddOperation  16.       facade = (Cu

55、stomerIntr) Naming.lookup ("rmi:/" +  17.                objAccountManager.getRMIHost() + ":" +  18.           

56、0;    objAccountManager.getRMIPort() +  19.                "/CustomerFacade");  20.       facade.setFName(firstName);  21.    

57、0;  facade.setLName(lastName);  22.       facade.setAddress(address);  23.            24.            25.       /Client&#

58、160;is not required to access subsystem components.  26.       boolean result = facade.saveCustomerData();  27.       if (result)   28.      

59、0;  validateCheckResult =  29.           " Valid Customer Data: Data Saved Successfully "  30.         else   31.         validateCheckResult =  32.           " Invalid Customer Data: Data Could Not Be Saved "  33.     

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論