代理模式與模板模式_第1頁
代理模式與模板模式_第2頁
代理模式與模板模式_第3頁
代理模式與模板模式_第4頁
代理模式與模板模式_第5頁
已閱讀5頁,還剩20頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、依賴(Dependency):虛線箭頭表示:A的變化會影響元素B,但反之不成立,那么B和A的關(guān)系是依賴關(guān)系,B依賴A;類屬關(guān)系和實現(xiàn)關(guān)系在語義上講也是依賴關(guān)系,但由于其有更特殊的用途,所以被單獨描述。uml中用帶箭頭的虛線表示Dependency關(guān)系,箭頭指向被依賴元素。Association):實線箭頭表示:元素間的結(jié)構(gòu)化關(guān)系,是一種弱關(guān)系,被關(guān)聯(lián)的元素間通??梢员华毩⒌目紤]。uml中用實線表示Association關(guān)系,箭頭指向被依賴元素。其中帶箭頭是單向關(guān)聯(lián),無箭頭即一個實線是雙向關(guān)聯(lián)。UML類圖說明1聚合(Aggregation):帶空心菱形頭表示:關(guān)聯(lián)關(guān)系的一種特例,表示部分和整體(

2、整體 has a 部分)的關(guān)系。uml中用帶空心菱形頭的實線表示Aggregation關(guān)系,菱形頭指向整體。合成/組合(Composition):帶實心菱形頭的實線表示:組合是聚合關(guān)系的變種,表示元素間更強(qiáng)的組合關(guān)系。如果是組合關(guān)系,如果整體被破壞則個體一定會被破壞,而聚合的個體則可能是被多個整體所共享的,不一定會隨著某個整體的破壞而被破壞。uml中用帶實心菱形頭的實線表示Composition關(guān)系,菱形頭指向整體。2泛化(Generalization):通常所說的繼承(特殊個體 is kind of 一般個體)關(guān)系,不必多解釋了。uml中用帶空心箭頭的實線線表示Generalization關(guān)

3、系,箭頭指向一般個體。實現(xiàn)(Realize):元素A定義一個約定,元素B實現(xiàn)這個約定,則B和A的關(guān)系是Realize,B realize A。這個關(guān)系最常用于接口。uml中用空心箭頭和虛線表示Realize關(guān)系,箭頭指向定義約定的元素。3代理模式的定義 代理模式(Proxy Pattern), 為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下 ,一個客戶不 想或者不能直接引用另一個對象,而代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用。 代理模式一般涉及到的角色有:抽象角色:聲明真實對象和代理對象的共同接口;代理角色:代理對象角色內(nèi)部含有對真實對象的引用,從而可以操作真實對象,同時

4、代理對象提供與真實對象相同的接口以便在任何時刻都能代替真實對象。并且,代理對象可以在執(zhí)行真實對象操作時,附加其他的操作,相當(dāng)于對真實對象進(jìn)行封裝。真實角色:代理角色所代表的真實對象,是我們最終要引用的對象。4代理模式的基本UML類圖Subject obj = new Proxy ()5代理模式的基本時序圖6動機(jī)1.為了在我們確實需要這個對象時才對它進(jìn)行創(chuàng)建和初始化。2.用戶希望程序和某個對象打交道,程序不希望用戶直接訪問該對象為什么要使用Proxy模式?7/抽象角色:abstract public class Subject abstract public void request();/真實

5、角色:實現(xiàn)了Subject的request()方法。public class RealSubject extends Subject public RealSubject() public void request() System.out.println(From real subject.); 代理實例8/代理角色:public class ProxySubject extends Subject private RealSubject realSubject; /以真實角色作為代理角色屬性 public ProxySubject() public void request() /該方法封

6、裝了真實對象的request方法 preRequest(); if( realSubject = null ) realSubject = new RealSubject(); realSubject.request(); /此處執(zhí)行真實對象的request方法 postRequest(); private void preRequest() /something you want to do before requesting private void postRequest() /something you want to do after requesting 9/客戶端調(diào)用:Subje

7、ct sub=new ProxySubject();Sub.request();由以上代碼可以看出,客戶實際需要調(diào)用的是RealSubject類的request()方法,現(xiàn)在用ProxySubject來代理RealSubject類,同樣達(dá)到目的,同時還封裝了其他方法(preRequest(),postRequest(),可以處理一些其他問題。 另外,如果要按照上述的方法使用代理模式,那么真實角色必須是事先已經(jīng)存在的,并將其作為代理對象的內(nèi)部屬性。但是實際使用時,一個真實角色必須對應(yīng)一個代理角色,如果大量使用會導(dǎo)致類的急劇膨脹;此外,如果事先并不知道真實角色,該如何使用代理呢?這個問題可以通過J

8、ava的動態(tài)代理類來解決。10動態(tài)代理 所謂Dynamic Proxy是這樣一種class:它是在運行時生成的class,在生成它時你必須提供一組interface給它,然后該class就宣稱它實現(xiàn)了這些interface。你當(dāng)然可以把該class的實例當(dāng)作這些interface中的任何一個來用。當(dāng)然啦,這個Dynamic Proxy其實就是一個Proxy,它不會替你作實質(zhì)性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。 Java動態(tài)代理類位于Java.lang.reflect包下,一般主要涉及到以下兩個類: (1). Interface InvocationHan

9、dler:該接口中僅定義了一個方法Object:invoke(Object obj,Method method, Object args)。在實際使用時,第一個參數(shù)obj一般是指代理類,method是被代理的方法,如上例中的request(),args為該方法的參數(shù)數(shù)組。這個抽象方法在代理類中動態(tài)實現(xiàn)。(2).Proxy:該類即為動態(tài)代理類,作用類似于上例中的ProxySubject,其中主要包含以下內(nèi)容:11Protected Proxy(InvocationHandler h):構(gòu)造函數(shù), 參數(shù)為InvocationHandler 實現(xiàn)類的實例。 Static Class getProxy

10、Class (ClassLoader loader, Class interfaces):獲得一個代理類,其中l(wèi)oader是類裝載器,interfaces是真實類所擁有的全部接口的數(shù)組。Static Object newProxyInstance(ClassLoader loader, Class interfaces, InvocationHandler h):返回代理類的一個實例,返回后的代理類可以當(dāng)作被代理類使用(可使用被代理類的在Subject接口中聲明過的方法)。 在使用動態(tài)代理類時,我們必須實現(xiàn)InvocationHandler接口,以第一個示例為例:12/抽象角色(之前是抽象類,

11、此處應(yīng)改為接口):public interface Subject public void request(); /具體角色RealSubject:實現(xiàn)了Subject接口的request()方法。public class RealSubject implements Subject public RealSubject() public void request() System.out.println(From real subject.); 13/代理角色:import java.lang.reflect.Method;import java.lang.reflect.Invocatio

12、nHandler;public class DynamicSubject implements InvocationHandler private Object target; public DynamicSubject(Object target) this. target = target; public Object invoke(Object proxy, Method method, Object args) throws Throwable System.out.println(before calling + method); method.invoke(sub,args); S

13、ystem.out.println(after calling + method); return null; 14/客戶端測試import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class Client static public void main(String args) throws Throwable RealSubject rs = new RealSubject(); /在這里指定被代理類 InvocationHandler ds = new DynamicSubject

14、(rs); /初始化代理類 Subject subject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),rs.getClass().getInterfaces(),ds); subject.request(); 通過這種方式,被代理的對象(RealSubject)可以在運行時動態(tài)改變,需要控制的接口(Subject接口)可以在運行時改變,控制的方式(DynamicSubject類)也可以動態(tài)改變,從而實現(xiàn)了非常靈活的動態(tài)代理關(guān)系。15代理模式的應(yīng)用一般來說分為幾種:遠(yuǎn)程(Remote)代理:也就是為一個對象

15、在不同的地址空間提供局部代表。這樣可以隱藏一個對象存在于不同地址空間的事實。虛擬(Virtual)代理:根據(jù)需要將一個資源消耗很大或者比較復(fù)雜的對象延遲的真正需要時才創(chuàng)建。 比如說你打開一個很大的HTML網(wǎng)頁時,里面可能有很多的文字和圖片,但你還是可以很快的打開它,此時你所看到的是所有的文字,但圖片卻是一張張的下載后才能看到。那些未打開的圖片框,就是通過虛擬代理來代替了真實的圖片,此時代理存儲了真實圖片的路徑和尺寸。保護(hù)(Protect or Access)代理:控制對一個對象的訪問權(quán)限。一般用于對象有 不同權(quán)限的時候。智能引用(Smart Reference)代理:當(dāng)調(diào)用真實對象時,代理出來

16、另外一些事,提供比對目標(biāo)對象額外的服務(wù)。 如:計算真實對象的引用次數(shù),這樣當(dāng)該對象沒有引用時,可以自動釋放它;或當(dāng)?shù)谝淮我靡粋€持久對象時,將它裝入內(nèi)存;或在訪問一個實際對象前,檢查是否已經(jīng)鎖定它,以確保其它對象不能改變它。它們都是通過代理在訪問一個對象時附加一些內(nèi)務(wù)處理。16遠(yuǎn)程代理( Remote Proxy ) 為一個對象在不同的地址空間提供局部代表。這樣可以隱藏一個對象存在于不同地址空間的事實。 RMI(remote method invocation)是一種分布式技術(shù),使用RMI可以讓一個虛擬機(jī)上的應(yīng)用程序請求調(diào)用位于網(wǎng)絡(luò)上另一個JVM上的對象方法。RMI不希望客戶應(yīng)用程序直接與遠(yuǎn)程

17、對象打交道,代替地讓應(yīng)用程序和遠(yuǎn)程對象的代理打交道。RMI會生成一個存根:一種特殊的字節(jié)碼,并讓這個存根產(chǎn)生的對象作為遠(yuǎn)程對象的代理,即遠(yuǎn)程代理。17虛代理代理通常擁有與實際對象基本相同的接口。代理的工作方式是:把服務(wù)請求明智地轉(zhuǎn)發(fā)給代理控制的底層對象,最終完成任務(wù)。對于大數(shù)據(jù)量的加載,VirtualProxy模式可以讓加載在后臺進(jìn)行,前臺用的Prxoy對象使得整體運行速度加快。18保護(hù)代理控制對一個對象的訪問權(quán)限。一般用于不同客戶對對象擁有 不同訪問權(quán)限的時候。結(jié)構(gòu)上,保護(hù)代理和遠(yuǎn)程代理以及虛代理是極為相似的,只是在請求訪問真實對象時提供的功能不同。區(qū)別:遠(yuǎn)程代理向客戶隱藏了遠(yuǎn)端機(jī)器或進(jìn)程上

18、的對象,虛代理負(fù)責(zé)管理了真實對象的加載方式。而保護(hù)代理則為用戶訪問對象的權(quán)限進(jìn)行管理19模板模式模板模式是所有模式中最為常見的幾個模式之一,是基于繼承的代碼復(fù)用的基本技術(shù)。模板模式需要開發(fā)抽象類和具體子類的設(shè)計師之間的協(xié)作。一個設(shè)計師負(fù)責(zé)給出一個算法的輪廓和骨架,另一些設(shè)計師則負(fù)責(zé)給出這個算法的各個邏輯步驟。代表這些具體邏輯步驟的方法稱做基本方法(primitive method);而將這些基本方法匯總起來的方法叫做模板方法(template method)。模板方法所代表的行為稱為頂級行為,其邏輯稱為頂級邏輯。模板方法模式的靜態(tài)結(jié)構(gòu)圖如下所示:20這里涉及到兩個角色:抽象模板類與具體模板類抽

19、象模板(Abstract Template)角色有如下責(zé)任:定義了一個或多個抽象操作,以便讓子類實現(xiàn)。這些抽象操作叫做基本操作,它們是一個頂級邏輯的組成步驟。定義并實現(xiàn)了一個模板方法。這個模板方法一般是一個具體方法,它給出了一個頂級邏輯的骨架,而邏輯的組成步驟在相應(yīng)的抽象操作中,推遲到子類實現(xiàn)。頂級邏輯也有可能調(diào)用一些具體方法。具體模板(Concrete Template)角色又如下責(zé)任:實現(xiàn)父類所定義的一個或多個抽象方法,它們是一個頂級邏輯的組成步驟。每一個抽象模板角色都可以有任意多個具體模板角色與之對應(yīng),而每一個具體模板角色都可以給出這些抽象方法(也就是頂級邏輯的組成步驟)的不同實現(xiàn),從而

20、使得頂級邏輯的實現(xiàn)各不相同。21public abstract class AbstractTemplate /* * 模板方法 */ public void templateMethod() /調(diào)用基本方法 abstractMethod(); hookMethod(); concreteMethod(); /* * 基本方法的聲明(由子類實現(xiàn)) */ protected abstract void abstractMethod(); /* * 基本方法(空方法) */ protected void hookMethod() /* * 基本方法(已經(jīng)實現(xiàn)) */ private final void concreteMethod() /業(yè)務(wù)相關(guān)的代碼 22public class ConcreteTemplate extends AbstractTemplate /基本方法的實現(xiàn) Override public void abstractMethod() /業(yè)務(wù)相關(guān)的代碼 /重寫父類的方法 Override public void hookMethod() /業(yè)務(wù)相關(guān)的代碼 模板模式的關(guān)鍵是:子類可以置換掉父類的可變部分,但是子類卻不可

溫馨提示

  • 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

提交評論