日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式笔记15:代理模式(Proxy Pattern)

發布時間:2025/3/14 asp.net 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式笔记15:代理模式(Proxy Pattern) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、代理模式的內容

? ? ? ?代理模式為另一個對象提供一個替身或占位符以訪問這個對象。 ? ? ? ? 給某一個對象提供一個代理,并由代理對象控制對原對象的引用。代理模式的英文叫做Proxy或Surrogate,它是一種對象結構型模式。
? ? ? ? 所謂代理,就是一個人或者一個機構代表另一個人或者另一個機構采取行動。在一些情況下,一個客戶不想或者不能夠直接引用一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。 ? ? ? ? 一個例子就是Windows的快捷方式??旖莘绞绞撬玫某绦虻囊粋€代理。
  • 在某些情況下,一個客戶不想或者不能直接引用一個對象,此時可以通過一個稱之為“代理”的第三者來實現間接引用。代理對象可以在客戶端和目標對象之間起到中介的作用,并且可以通過代理對象去掉客戶不能看到的內容和服務或者添加客戶需要的額外服務。
  • 通過引入一個新的對象(如小圖片和遠程代理對象)來實現對真實對象的操作或者將新的對象作為真實對象的一個替身,這種實現機制即為代理模式,通過引入代理對象來間接訪問一個對象,這就是代理模式的模式動機。?

要點

  • 裝飾者模式為對象加上行為,而代理模式則是控制訪問。
  • 和裝飾者模式類似,代理模式會造成設計中類的數目增加。

二、?代理的種類

如果按照使用目的來劃分,代理有以下幾種:

  • 遠程(Remote)代理:為一個位于不同的地址空間的對象提供一個局域代表對象。這個不同的地址空間可以是在本機器中,也可是在另一臺機器中。遠程代理又叫做大使(Ambassador)。
  • 虛擬(Virtual)代理:根據需要創建一個資源消耗較大的對象,使得此對象只在需要時才會被真正創建。
  • Copy-on-Write代理:虛擬代理的一種。把復制(克隆)拖延到只有在客戶端需要時,才真正采取行動。
  • 保護(Protect or Access)代理:控制對一個對象的訪問,如果需要,可以給不同的用戶提供不同級別的使用權限。
  • Cache代理:為某一個目標操作的結果提供臨時的存儲空間,以便多個客戶端可以共享這些結果。
  • 防火墻(Firewall)代理:保護目標,不讓惡意用戶接近。
  • 同步化(Synchronization)代理:使幾個用戶能夠同時使用一個對象而沒有沖突。
  • 智能引用(Smart Reference)代理:當一個對象被引用時,提供一些額外的操作,比如將對此對象調用的次數記錄下來等。

在所有種類的代理模式中,虛擬(Virtual)代理、遠程(Remote)代理、智能引用代理(Smart Reference Proxy)和保護(Protect or Access)代理是最為常見的代理模式。

三、代理模式的結構


代理模式所涉及的角色有:

抽象主題角色(Subject):聲明了真實主題和代理主題的共同接口,這樣一來在任何使用真實主題的地方都可以使用代理主題。

代理主題(Proxy)角色:代理主題角色內部含有對真是主題的引用,從而可以在任何時候操作真實主題對象;代理主題角色提供一個與真實主題角色相同的接口,以便可以在任何時候都可以替代真實主體;控制真實主題的應用,負責在需要的時候創建真實主題對象(和刪除真實主題對象);代理角色通常在將客戶端調用傳遞給真實的主題之前或之后,都要執行某個操作,而不是單純的將調用傳遞給真實主題對象。

真實主題角色(RealSubject)角色:定義了代理角色所代表的真實對象。

四、代理模式示例代碼

代碼一、 抽象主題角色(Subject)

public interface AbstractPermission {public void modifyUserInfo();public void viewNote();public void publishNote();public void modifyNote();public void setLevel(int level); }

真實主題角色(RealSubject)角色

public class RealPermission implements AbstractPermission { public void modifyUserInfo(){System.out.println("修改用戶信息!");}public void viewNote(){ }public void publishNote(){System.out.println("發布新帖!");}public void modifyNote(){System.out.println("修改發帖內容!");}public void setLevel(int level){ } }代理主題(Proxy)角色
public class PermissionProxy implements AbstractPermission {private RealPermission permission=new RealPermission();private int level=0; public void modifyUserInfo(){if(0==level){System.out.println("對不起,你沒有該權限!");}else if(1==level){permission.modifyUserInfo();}}public void viewNote(){System.out.println("查看帖子!");}public void publishNote(){if(0==level){System.out.println("對不起,你沒有該權限!");}else if(1==level){permission.publishNote();} }public void modifyNote(){if(0==level){System.out.println("對不起,你沒有該權限!");}else if(1==level){permission.modifyNote();} }public void setLevel(int level){this.level=level;} }測試

<?xml version="1.0"?> <config><className>PermissionProxy</className> </config>import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.SAXException; import java.io.*; public class XMLUtil { //該方法用于從XML配置文件中提取具體類類名,并返回一個實例對象public static Object getBean(){try{//創建文檔對象DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = dFactory.newDocumentBuilder();Document doc; doc = builder.parse(new File("config.xml")); //獲取包含類名的文本節點NodeList nl = doc.getElementsByTagName("className");Node classNode=nl.item(0).getFirstChild();String cName=classNode.getNodeValue();//通過類名生成實例對象并將其返回Class c=Class.forName(cName);Object obj=c.newInstance();return obj;} catch(Exception e){e.printStackTrace();return null;}} } public class Client {public static void main(String args[]){AbstractPermission permission;permission=(AbstractPermission)XMLUtil.getBean();permission.modifyUserInfo();permission.viewNote();permission.publishNote();permission.modifyNote();System.out.println("----------------------------");permission.setLevel(1);permission.modifyUserInfo();permission.viewNote();permission.publishNote();permission.modifyNote();} }代碼二(動態代理)、

抽象主題

public interface AbstractSubject {public void request(); }真正主題

public class RealSubjectA implements AbstractSubject { public void request(){System.out.println("真實主題類A!");} }public class RealSubjectB implements AbstractSubject { public void request(){System.out.println("真實主題類B!");} }代理角色

import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class DynamicProxy implements InvocationHandler {private Object obj;public DynamicProxy(){}public DynamicProxy(Object obj){this.obj=obj;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{preRequest();method.invoke(obj, args);postRequest();return null;}public void preRequest(){System.out.println("調用之前!");}public void postRequest(){System.out.println("調用之后!");}}測試

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy;public class Client {public static void main(String args[]){InvocationHandler handler =null;AbstractSubject subject=null;handler=new DynamicProxy(new RealSubjectA());subject=(AbstractSubject)Proxy.newProxyInstance(AbstractSubject.class.getClassLoader(), new Class[]{AbstractSubject.class}, handler);subject.request();System.out.println("------------------------------");handler=new DynamicProxy(new RealSubjectB());subject=(AbstractSubject)Proxy.newProxyInstance(AbstractSubject.class.getClassLoader(), new Class[]{AbstractSubject.class}, handler);subject.request();} }


五、幾種常用的代理模式?

  • 圖片代理:一個很常見的代理模式的應用實例就是對大圖瀏覽的控制。?
? ? ? ? 用戶通過瀏覽器訪問網頁時先不加載真實的大圖,而是通過代理對象的方法來進行處理,在代理對象的方法中,先使用一個線程向客戶端瀏覽器加載一個小圖片,然后在后臺使用另一個線程來調用大圖片的加載方法將大圖片加載到客戶端。當需要瀏覽大圖片時,再將大圖片在新網頁中顯示。如果用戶在瀏覽大圖時加載工作還沒有完成,可以再啟動一個線程來顯示相應的提示信息。通過代理技術結合多線程編程將真實圖片的加載放到后臺來操作,不影響前臺圖片的瀏覽。
  • 遠程代理:遠程代理可以將網絡的細節隱藏起來,使得客戶端不必考慮網絡的存在。客戶完全可以認為被代理的遠程業務對象是局域的而不是遠程的,而遠程代理對象承擔了大部分的網絡通信工作。
  • 虛擬代理:當一個對象的加載十分耗費資源的時候,虛擬代理的優勢就非常明顯地體現出來了。虛擬代理模式是一種內存節省技術,那些占用大量內存或處理復雜的對象將推遲到使用它的時候才創建。
? ? ? ? 在應用程序啟動的時候,可以用代理對象代替真實對象初始化,節省了內存的占用,并大大加速了系統的啟動時間。
動態代理 ?
  • 動態代理是一種較為高級的代理模式,它的典型應用就是Spring AOP。
? ? ? ? 在傳統的代理模式中,客戶端通過Proxy調用RealSubject類的request()方法,同時還在代理類中封裝了其他方法(如preRequest()和postRequest()),可以處理一些其他問題。
? ? ? ? 如果按照這種方法使用代理模式,那么真實主題角色必須是事先已經存在的,并將其作為代理對象的內部成員屬性。如果一個真實主題角色必須對應一個代理主題角色,這將導致系統中的類個數急劇增加,因此需要想辦法減少系統中類的個數,此外,如何在事先不知道真實主題角色的情況下使用代理主題角色,這都是動態代理需要解決的問題。
? ? ? ? Java動態代理實現相關類位于java.lang.reflect包,主要涉及兩個類:
  • InvocationHandler接口。它是代理實例的調用處理程序實現的接口,該接口中定義了如下方法:public Object invoke (Object proxy, Method method, Object[] args) throws Throwable;invoke()方法中第一個參數proxy表示代理類,第二個參數method表示需要代理的方法,第三個參數args表示代理方法的參數數組。
  • ?Proxy類。該類即為動態代理類,該類最常用的方法為:public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException。newProxyInstance()方法用于根據傳入的接口類型interfaces返回一個動態創建的代理類的實例,方法中第一個參數loader表示代理類的類加載器,第二個參數interfaces表示代理類實現的接口列表(與真實主題類的接口列表一致),第三個參數h表示所指派的調用處理程序類。

  • 六、代理模式優缺點

    代理模式的優點
    • 代理模式能夠協調調用者和被調用者,在一定程度上降低了系統的耦合度。
    • 遠程代理使得客戶端可以訪問在遠程機器上的對象,遠程機器可能具有更好的計算性能與處理速度,可以快速響應并處理客戶端請求。
    • 虛擬代理通過使用一個小對象來代表一個大對象,可以減少系統資源的消耗,對系統進行優化并提高運行速度。
    • 保護代理可以控制對真實對象的使用權限。
    代理模式的缺點
    • 由于在客戶端和真實主題之間增加了代理對象,因此有些類型的代理模式可能會造成請求的處理速度變慢。
    • 實現代理模式需要額外的工作,有些代理模式的實現非常復雜。

    七、代理模式適用環境

    根據代理模式的使用目的,常見的代理模式有以下幾種類型:
  • 遠程(Remote)代理:為一個位于不同的地址空間的對象提供一個本地的代理對象,這個不同的地址空間可以是在同一臺主機中,也可是在另一臺主機中,遠程代理又叫做大使(Ambassador)。?
  • 虛擬(Virtual)代理:如果需要創建一個資源消耗較大的對象,先創建一個消耗相對較小的對象來表示,真實對象只在需要時才會被真正創建。?
  • Copy-on-Write代理:它是虛擬代理的一種,把復制(克隆)操作延遲到只有在客戶端真正需要時才執行。一般來說,對象的深克隆是一個開銷較大的操作,Copy-on-Write代理可以讓這個操作延遲,只有對象被用到的時候才被克隆。
  • 保護(Protect or Access)代理:控制對一個對象的訪問,可以給不同的用戶提供不同級別的使用權限。?
  • 緩沖(Cache)代理:為某一個目標操作的結果提供臨時的存儲空間,以便多個客戶端可以共享這些結果。
  • 防火墻(Firewall)代理:保護目標不讓惡意用戶接近。?
  • 同步化(Synchronization)代理:使幾個用戶能夠同時使用一個對象而沒有沖突。?
  • 智能引用(Smart Reference)代理:當一個對象被引用時,提供一些額外的操作,如將此對象被調用的次數記錄下來等。
  • 八、代理模式應用

    (1) Java RMI (Remote Method Invocation,遠程方法調用)。
    (2) EJB、Web Service等分布式技術都是代理模式的應用。在EJB中使用了RMI機制,遠程服務器中的企業級Bean在本地有一個樁代理,客戶端通過樁來調用遠程對象中定義的方法,而無須直接與遠程對象交互。在EJB的使用中需要提供一個公共的接口,客戶端針對該接口進行編程,無須知道樁以及遠程EJB的實現細節。?
    (3) Spring 框架中的AOP技術也是代理模式的應用,在Spring AOP中應用了動態代理(Dynamic Proxy)技術。?

    Proxy?(recognizeable by creational methods which returns an implementation of given abstract/interface type which in turn?delegates/uses?a?different?implementation of given abstract/interface type)

    • java.lang.reflect.Proxy
    • java.rmi.*, the whole API actually.

    The Wikipedia example is IMHO a bit poor, lazy loading has actually completely nothing to do with the proxy pattern at all.

    九、參考資料

  • 《設計模式》劉偉主編清華大學出版社
  • 《Head First 設計模式》
  • http://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns

  • 轉載于:https://www.cnblogs.com/snowberg/archive/2012/06/17/2618921.html

    總結

    以上是生活随笔為你收集整理的设计模式笔记15:代理模式(Proxy Pattern)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。