代理设计模式的目的就是在不直接操作对象的前提下对对象进行访问,实现这个目的得方法就是为目标对象创建一个代理(Proxy),通过代理来访问目标对象。这个设计模式的优点是什么呢?代码重用,符合开闭原则。
这样解释可能会不太好理解,那么接下来就通俗的来说一下代理:
1,不知道你知不知道VPN(也就是俗称的科学上网),在党的领导下,为了营造我国健康的的网络环境国外的一些网站在我国是无法访问的。例如:google。但是因为某些行业的特殊性需要访问这些国内不可访问的网站,那么怎么办呢?这个时候就需要代理(正向代理)了,怎么实现呢?例如:香港可以访问国内不可访问的网站,而国内却可以访问香港的网站。那么就可以这样做“国内->香港服务器(代理)->国外网站”。这里就用到了代理。
2,更通俗的例子就是,作者小的时候被狗狗追着跑,所以到现在作者看到狗狗,特别是体型庞大的狗狗的时候,就会害怕。假如一个狗狗有一天突然抢了作者的包子,那怎么办呢?那只能委托狗狗的主人,让狗狗把包子还给作者(r如果狗狗还没吃掉)。这里的主人也是扮演了代理的角色。
二,动态代理代码示例
那么接下来就以上面说到第三个例子,用代码展示一下代理模式。代理模式分为静态代理和动态代理,本文只说明动态代理。
1packagecom.zcz.proxyTest.testtwo;23publicinterfaceSinger{4/**5*根据歌名点歌6*@paramsongName7*/8publicvoidorderSong(StringsongName);9/**10*向观众告别11*@paramaudienceName12*/13publicvoidsayGoodBye(StringaudienceName);14}2,接下来实现王力宏类,并实现接口中的两个方法。
packagecom.zcz.proxyTest.testtwo;publicclassWangLiHongimplementsSinger{@OverridepublicvoidorderSong(StringsongName){//TODOAuto-generatedmethodstubSystem.out.println("演唱歌曲:"+songName);}@OverridepublicvoidsayGoodBye(StringaudienceName){//TODOAuto-generatedmethodstubSystem.out.println("再见:"+audienceName);}}3,就算我找到了经纪人(代理),那我也不能随便就叫经纪人通知(调用)王力宏(目标对象)唱歌(的方法),我还要准备一个感人肺腑的故事,但是我又不会讲故事,这个时候,经纪人就提供给了我一个模板(调用处理类,一个接口),让我按照模板编写故事(实现invoke方法)
4,OK,到这里所有的准备工作就完成了,接下来就开始吧。
packagecom.zcz.proxyTest.testtwo;importjava.lang.reflect.Proxy;publicclassMyPorxy{publicstaticvoidmain(String[]args){//实例化目标对象(创造一个力宏)WangLiHongliHong=newWangLiHong();//实例化调用处理类(编好的故事)MyStoryInvocationHandlerhandler=newMyStoryInvocationHandler(liHong);//接下来创建代理(经纪人)//准备一个类加载器ClassLoaderloader=MyPorxy.class.getClassLoader();//获取目标对象的接口类对象数组Class<>[]interfaces=liHong.getClass().getInterfaces();//创建代理Singerproxy=(Singer)Proxy.newProxyInstance(loader,interfaces,handler);//开始点歌proxy.orderSong("就是现在");System.out.println("******歌唱中......********");//歌唱完了,saygoodBye吧proxy.sayGoodBye("zhangchengzi");}}5,好,现在右键->RunAs->JavaApplication。看打印结果:
力宏,我是你代理经纪人:com.sun.proxy.$Proxy0巴拉巴拉......(讲了一个故事)传入的参数:就是现在演唱歌曲:就是现在巴拉巴拉,感谢........******歌唱中......********力宏,我是你代理经纪人:com.sun.proxy.$Proxy0巴拉巴拉......(讲了一个故事)传入的参数:zhangchengzi再见:zhangchengzi巴拉巴拉,感谢........6,看到了吗?我们不没有直接使用目标对象的方法,而是构造出一个代理对象,通过代理来访问了目标对象的方法。总结一下,想要实现动态代理需要四个关键元素