设计模式(四)--代理模式
設(shè)計(jì)模式(四)–代理模式
文章目錄
- 設(shè)計(jì)模式(四)--代理模式
- 其他鏈接
- 代理模式
- 1.簡介
- 2.靜態(tài)代理
- 角色
- 代碼實(shí)現(xiàn)
- 好處
- 3.動(dòng)態(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)中,一個(gè)類代表另一個(gè)類的功能。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式。
在代理模式中,我們創(chuàng)建具有現(xiàn)有對象的對象,以便向外界提供功能接口。
代理模式又分以下兩種:
-
靜態(tài)代理
-
動(dòng)態(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.動(dòng)態(tài)代理
學(xué)動(dòng)態(tài)代理最重要是get到那個(gè)動(dòng)的概念,過于理論是很難理解動(dòng)態(tài)代理的,結(jié)合代碼實(shí)踐反而易于理解。動(dòng)態(tài)代理的核心就是通過反射機(jī)制實(shí)現(xiàn)的,通過反射獲得被代理類的方法和調(diào)用執(zhí)行器的方法。
- 動(dòng)態(tài)代理和靜態(tài)代理角色一樣
- 動(dòng)態(tài)代理的代理類是動(dòng)態(tài)生成的
- 動(dòng)態(tài)代理分兩大類:
- 基于接口的動(dòng)態(tài)代理
- 基于類的動(dòng)態(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)代理那套的話 ,這里要寫代理角色的,但是動(dòng)態(tài)代理不同,動(dòng)態(tài)代理的代理角色是動(dòng)態(tài)生成的,這也是體現(xiàn)其動(dòng)的表現(xiàn)。我們通過這個(gè)代理執(zhí)行其去動(dòng)態(tài)生成代理類。
- InvocationHandler是java reflect包下的接口,其提供了invoke方法接口,用于代理角色的方法執(zhí)行接口。
- Proxy 也是java reflect包下的,其提供了一個(gè)靜態(tài)方法放回一個(gè)動(dòng)態(tài)代理類。
如果上面兩個(gè)沒聽懂的話,無所謂,只要記住Proxy提供放回一個(gè)動(dòng)態(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(){//返回動(dòng)態(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{/*動(dòng)態(tài)代理類一旦調(diào)用接口方法,就會(huì)執(zhí)行invoke方法,在這里可以對method.getName()做判斷,看看是調(diào)用了那個(gè)接口方法。*/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);//放回動(dòng)態(tài)代理Rent hostProxy = (Rent)pih.getProxy();//動(dòng)態(tài)代理調(diào)用接口方法hostProxy.rent();} }解析
上面代碼執(zhí)行流程開始解析:
機(jī)制解析:
核心:就是通過反射機(jī)制獲得被代理類的方法和調(diào)用執(zhí)行器的方法。
有人就會(huì)問,為什么Proxy放回的動(dòng)態(tài)代理會(huì)有被代理類的接口方法?
- 那是因?yàn)榘?#xff0c;在newProxyInstance()時(shí),你告知Proxy 被代理類的接口是那個(gè)(interfaces參數(shù)),所以放回的動(dòng)態(tài)代理是實(shí)現(xiàn)了被代理類的接口方法的。
那為什么調(diào)用被代理類的接口的方法是去調(diào)用了ProxyInvocationHandler的invoke()方法呢?
- 這就是動(dòng)態(tài)代理的精髓了,當(dāng)你給Proxy.newProxyInstance()方法傳遞InvocationHandler接口的實(shí)現(xiàn)類及其實(shí)現(xiàn)類的加載器的時(shí)候,Proxy其實(shí)就是完全拿到了那個(gè)類了,完全可以通過反射和這個(gè)類的加載器來創(chuàng)建該InvocationHandler接口的實(shí)現(xiàn)類,當(dāng)你調(diào)用被代理類的接口方法rent()時(shí),其實(shí)內(nèi)部就是調(diào)用invoke()方法,并且給invoke方法傳遞你調(diào)用的是那個(gè)接口方法,還有其傳遞的參數(shù)。
總結(jié)
以上是生活随笔為你收集整理的设计模式(四)--代理模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 头发变软了是什么原因
- 下一篇: MySQL深入(一)