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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式(四)--代理模式

發(fā)布時間:2024/9/19 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式(四)--代理模式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

設(shè)計(jì)模式(四)–代理模式

文章目錄

  • 設(shè)計(jì)模式(四)--代理模式
    • 其他鏈接
    • 代理模式
      • 1.簡介
      • 2.靜態(tài)代理
        • 角色
        • 代碼實(shí)現(xiàn)
        • 好處
      • 3.動態(tài)代理
        • 代碼實(shí)現(xiàn)
        • 解析

其他鏈接

JVM學(xué)習(xí)筆記(一)
JVM學(xué)習(xí)筆記(二)
JVM學(xué)習(xí)筆記(三)
JVM學(xué)習(xí)筆記(四)
(待更新…)

Java NIO
(待更新…)

設(shè)計(jì)模式(一)
設(shè)計(jì)模式(二)
設(shè)計(jì)模式(三)
設(shè)計(jì)模式(四)
(待更新…)

代理模式

1.簡介

在代理模式(Proxy Pattern)中,一個類代表另一個類的功能。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式。

在代理模式中,我們創(chuàng)建具有現(xiàn)有對象的對象,以便向外界提供功能接口。

代理模式又分以下兩種:

  • 靜態(tài)代理

  • 動態(tài)代理

2.靜態(tài)代理

角色

  • 抽象角色:接口或抽象類,統(tǒng)一操作標(biāo)準(zhǔn)
  • 真實(shí)角色:被代理的角色(如房東)
  • 代理角色:負(fù)責(zé)代理真實(shí)角色,代理真實(shí)角色去做其附屬操作(如中間商)
  • 客戶:訪問代理的人。(如租客)

代碼實(shí)現(xiàn)

租房接口—抽象角色

public interface Rent{//出租房子public void rent(); }

房東類----真實(shí)角色

public class Host implements Rent{//租房子public void rent(){System.out.println("出租房子");} }

代理類—代理角色

public class Proxy implements Rent{private Host host;public Proxy(){}public Proxy(Host host){this.host = host;}//代理方法public void rent(){//代理角色給真實(shí)角色擴(kuò)展了功能this.money();host.rent();this.seeHouse();}//一些代理的附屬操作public void money(){System.out.println("代理收錢");}public void seeHouse(){System.out.println("代理帶你看房子");} }

客戶類—客戶

public class Client{public static void main(String[] args){Host host = new Host();Proxy proxy = new Proxy(host);proxy.rent();} }

好處

1、代理模式能將代理對象與真實(shí)被調(diào)用的目標(biāo)對象分離。

2、一定程度上降低了系統(tǒng)的耦合度,擴(kuò)展性好。

3、可以起到保護(hù)目標(biāo)對象的作用。

4、可以對目標(biāo)對象的功能增強(qiáng)。

3.動態(tài)代理

學(xué)動態(tài)代理最重要是get到那個動的概念,過于理論是很難理解動態(tài)代理的,結(jié)合代碼實(shí)踐反而易于理解。動態(tài)代理的核心就是通過反射機(jī)制實(shí)現(xiàn)的,通過反射獲得被代理類的方法和調(diào)用執(zhí)行器的方法。

  • 動態(tài)代理和靜態(tài)代理角色一樣
  • 動態(tài)代理的代理類是動態(tài)生成的
  • 動態(tài)代理分兩大類:
    • 基于接口的動態(tài)代理
    • 基于類的動態(tài)代理

代碼實(shí)現(xiàn)

租房接口—抽象角色

public interface Rent{//出租房子public void rent(); }

房東類----真實(shí)角色

public class Host implements Rent{//租房子public void rent(){System.out.println("出租房子");} }

代理調(diào)用執(zhí)行器

如果按靜態(tài)代理那套的話 ,這里要寫代理角色的,但是動態(tài)代理不同,動態(tài)代理的代理角色是動態(tài)生成的,這也是體現(xiàn)其動的表現(xiàn)。我們通過這個代理執(zhí)行其去動態(tài)生成代理類。

  • InvocationHandler是java reflect包下的接口,其提供了invoke方法接口,用于代理角色的方法執(zhí)行接口。
  • Proxy 也是java reflect包下的,其提供了一個靜態(tài)方法放回一個動態(tài)代理類。

如果上面兩個沒聽懂的話,無所謂,只要記住Proxy提供放回一個動態(tài)代理角色的方法,而實(shí)現(xiàn)InvocationHandler接口的類可以通過invoke()執(zhí)行代理方法即可。

public class ProxyInvocationHandler implements InvocationHandler{//被代理的接口private Object target;public void setTarget(Object target){this.target = target;}public Object getProxy(){//返回動態(tài)代理類/*Proxy的靜態(tài)方法newProxyInstance返回的是代理對象,參數(shù)如下:(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)loader:實(shí)現(xiàn)InvocationHandler接口的類的加載器interfaces:被代理類的接口h:實(shí)現(xiàn)InvocationHandler的類*/return Proxy.newProxyInstance(this.getClass().getClassLoad(),target.getClass().getInterfaces(),this)}@Overridepublic Object invoke(Object proxy,Method method,Object[] args) throws Throwable{/*動態(tài)代理類一旦調(diào)用接口方法,就會執(zhí)行invoke方法,在這里可以對method.getName()做判斷,看看是調(diào)用了那個接口方法。*/System.out.println("這里可以添加代理操作!!!");Object result = method.invoke(this.target,args)return result;}}

客戶類—客戶

public class Client{public static void main(String[] args){//創(chuàng)建被代理的類Host host = new Host();//創(chuàng)建代理調(diào)用執(zhí)行器ProxyInvocationHandler pih = new ProxyInvocationHandler();//設(shè)置代理對象pih.setTarget(host);//放回動態(tài)代理Rent hostProxy = (Rent)pih.getProxy();//動態(tài)代理調(diào)用接口方法hostProxy.rent();} }

解析

上面代碼執(zhí)行流程開始解析:

  • 創(chuàng)建被代理的類,這沒什么好說的。
  • 創(chuàng)建好代理調(diào)用執(zhí)行器,該執(zhí)行器實(shí)現(xiàn)了InvocationHandler接口,并且我還創(chuàng)建了getProxy()方法,使其能放回動態(tài)代理類。
  • 調(diào)用setTarget(host)給該代理調(diào)用執(zhí)行器綁定要被代理的對象
  • 調(diào)用getProxy()方法,這步就好好好解析了,看看Proxy.newProxyInstance()的參數(shù),這些參數(shù)告知了Proxy,被代理類有哪些接口方法(就是實(shí)現(xiàn)了那個接口方法interfaces),也告知了Proxy哪些類實(shí)現(xiàn)了InvocationHandler接口,并及其類的加載器。這些參數(shù)告知了放回了代理類應(yīng)該有哪些方法,當(dāng)這些方法被調(diào)用時,應(yīng)該去找那個InvocationHandler接口的實(shí)現(xiàn)類去執(zhí)行。
  • 代理類執(zhí)行rent()接口方法,實(shí)踐上是去調(diào)用了ProxyInvocationHandler中的invoke()方法。

  • 機(jī)制解析:

    核心:就是通過反射機(jī)制獲得被代理類的方法和調(diào)用執(zhí)行器的方法。

    有人就會問,為什么Proxy放回的動態(tài)代理會有被代理類的接口方法?

    • 那是因?yàn)榘?#xff0c;在newProxyInstance()時,你告知Proxy 被代理類的接口是那個(interfaces參數(shù)),所以放回的動態(tài)代理是實(shí)現(xiàn)了被代理類的接口方法的。

    那為什么調(diào)用被代理類的接口的方法是去調(diào)用了ProxyInvocationHandler的invoke()方法呢?

    • 這就是動態(tài)代理的精髓了,當(dāng)你給Proxy.newProxyInstance()方法傳遞InvocationHandler接口的實(shí)現(xiàn)類及其實(shí)現(xiàn)類的加載器的時候,Proxy其實(shí)就是完全拿到了那個類了,完全可以通過反射和這個類的加載器來創(chuàng)建該InvocationHandler接口的實(shí)現(xiàn)類,當(dāng)你調(diào)用被代理類的接口方法rent()時,其實(shí)內(nèi)部就是調(diào)用invoke()方法,并且給invoke方法傳遞你調(diào)用的是那個接口方法,還有其傳遞的參數(shù)。

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。