浅析JAVA设计模式之代理模式(三)
2014-05-04 16:18
591 查看
1. 抽象接口有多个方法的情况
在《浅析JAVA设计模式之代理模式(一)》(简称《一》)和《浅析JAVA设计模式之代理模式(二)》(简称《二》)中,抽象方法里面只有一个方法,如果有一个以上的方法需要代理,我们的代码又该如何写?1.1 静态代理的处理
(1)现在改动一下《一》中的Subject.Java文件,增加一个方法。package StaticProxy; public interface Subject { public void print(String words); public void print2(String words); }
(2)相应的《一》中的被代理类(RealSubject.java)进行改动。
package StaticProxy; publicclass RealSubject implements Subject{ publicvoid print(String words) { System.out.println("被代理的人郭襄说:"+words); } publicvoid print2(String words) { System.out.println("被代理的人郭襄2说:"+words); } }
(3)相应的《一》中的代理类(ProxySubject.java)进行改动。
package StaticProxy; public class ProxySubject implements Subject{ private Subject s; public ProxySubject(Subject s){ this.s=s; } public void print(String words) { System.out.println("我是代理,我的名字叫黄蓉!"); //调用实际的被代理的方法print() s.print(words); System.out.println("黄蓉代理完毕!"); } public void print2(String words) { System.out.println("我是代理,我的名字叫黄蓉!"); //调用实际的被代理的方法print2() s.print2(words); System.out.println("黄蓉代理完毕!"); } }(4)再修改一下客户端程序(TestSubject.java)。
package StaticProxy; public class TestSubject { public static void main(String []args){ Subject sub1=new RealSubject();//创建真实对象(被代理对象) Subject sub2=new ProxySubject(sub1);//创建代理对象,把被代理对象传进去 sub2.print("你好!"); //调用代理方法print() System.out.println(); sub2.print2("你坏!"); //调用代理方法print2() } }
输出结果:
我是代理,我的名字叫黄蓉!
被代理的人郭襄说:你好!
黄蓉代理完毕!
我是代理,我的名字叫黄蓉!
被代理的人郭襄2说:你坏!
黄蓉代理完毕!
从结果可以看出,当有多个方法需要代理的时候,静态代理还是很好实现的,当不同的方法被调用时,相应的处理也会被调用。
但是,如果一个被代理类有多个方法,而这些方法调用前后都有着相同的处理方式,那么静态代理中的代理类就要在不同的方法里面写着相同的代码,如果某一天改动了一下,所有的代码都要全部改动一次,这样非常不好,这种情况使用《二》的动态代理只需要在LogHandler.java中的invoke(
)方法中写一次即可。
1.2 动态代理的处理
(1)如果是对抽象接口中不同的方法都有相同的处理逻辑,只需要把《二》的Proxy.java改动一小下,把里面的newProxyInstance()方法下的methodString=改成methodString+=即可,其中methodString=只适用于抽象接口只有1个方法,methodString+=适用于抽象接口有1个或1个以上方法。(2)如果对抽象接口中不同的方法有不相同的处理逻辑,情况就有点变化。现在改动一下《二》中的Subject.Java文件,增加一个方法。
package dynamicProxy; public interface Subject { public void print(); public void print2(); }
(3)相应的《二》中的被代理类(RealSubject.java)进行改动。
package dynamicProxy; public class RealSubject implements Subject{ public void print() { System.out.println("被代理的人郭襄"); } public void print2() { System.out.println("被代理的人郭襄2"); } }
(4)相应的《二》中的处理器类(LogHandler.java)进行改动。
package dynamicProxy; import java.lang.reflect.*; public class LogHandler implements InvocationHandler{ private Object delegate; //被代理类的对象 //绑定被代理类的对象 public Object bind(Object delegate)throws Exception{ this.delegate=delegate; //Proxy就是要生成代理类的类,Subject.class 是要被代理的类所实现的接口 return Proxy.newProxyInstance(Subject.class,this); } public Object invoke(Object proxy, Method method) throws Exception { String name=method.getName(); Object result=null; if(name.equals("print")){ System.out.println("我是代理人黄蓉,开始代理"); result=method.invoke(delegate); System.out.println("我是代理人黄蓉,代理完毕"); } if(name.equals("print2")) { System.out.println("我是代理人黄蓉2,开始代理"); result=method.invoke(delegate); System.out.println("我是代理人黄蓉2,代理完毕"); } return result; } }
(5)相应的《二》中的测试客户端(TestDynamicProxy.java)进行改动。
package dynamicProxy; public class TestDynamicProxy { public static void main(String[] args)throws Exception { Subject sub1=new RealSubject(); LogHandler hander=new LogHandler(); Subject sub2=(Subject)hander.bind(sub1); sub2.print(); sub2.print2(); } }
输出结果:
我是代理人黄蓉,开始代理
被代理的人郭襄
我是代理人黄蓉,代理完毕
我是代理人黄蓉2,开始代理
被代理的人郭襄2
我是代理人黄蓉2,代理完毕
(6)生成的$Proxy.java文件如下,可看出抽象接口的每个方法都已经被代理。
package dynamicProxy; import java.lang.reflect.Method; public class $Proxy implements Subject{ private dynamicProxy.InvocationHandler h; public $Proxy(InvocationHandler h) { super(); this.h = h; } public void print2(){ try{ Method md=Subject.class.getMethod("print2"); h.invoke(this,md); }catch (Exception e){ e.printStackTrace(); } } public void print(){ try{ Method md=Subject.class.getMethod("print"); h.invoke(this,md); }catch (Exception e){ e.printStackTrace(); } } }
结果可以看出,对不同的方法实现了不同的处理逻辑,而且还可以把处理逻辑写成配置式的,这里就不详细说明。
动态代理的明显好处这里就体现出来了:
1.对于同一个对象的所有方法,如果对所有方法都是相同的处理逻辑,只需要写一次处理逻辑就行。
2.对于同一个抽象接口,不同的对象,如果对所有对象的相同名字的方法具有相同的处理逻辑(同一个对象,不同方法的处理逻辑可以不同),也只需要写一次处理逻辑就行,只需要写一次处理器类即可。
3.如果某一天,那个方法的处理逻辑被改变了,只需要改动一次即可,如果是静态代理,每个代理类下的相对应的方法的处理逻辑都要改动一次,维护非常困难。
推荐文章:
浅析JAVA设计模式之代理模式(一)
/article/8700144.html
浅析JAVA设计模式之代理模式(二)
/article/8700145.html
浅析JAVA设计模式之代理模式(四)
/article/8700147.html
浅析JAVA设计模式之代理模式(五)
/article/8700148.html
浅析JAVA设计模式之代理模式(六)
/article/8699158.html
浅析JAVA设计模式之代理模式(七)
/article/8699159.html
Author: Vicky
Introduction: 教育工作者
Sign: 读书得可道之道,实践悟不可道之道
相关文章推荐
- 浅析JAVA设计模式之代理模式(二)
- 浅析JAVA设计模式之代理模式(一)
- java 设计模式 —— 浅析代理模式
- 浅析JAVA设计模式之代理模式(五)
- 浅析JAVA设计模式之代理模式(七)
- 浅析JAVA设计模式之代理模式(四)
- 浅析JAVA设计模式之代理模式(六)
- Java设计模式之计数代理模式
- java设计模式之代理模式
- 0102 Java设计模式02-代理模式【进阶】
- Java设计模式---代理模式(二)---动态代理
- JAVA设计模式:代理模式
- java23种设计模式 代理模式(五)
- Java设计模式之代理模式
- java 设计模式之静态代理模式
- 浅析Java设计模式 - 单例模式
- Java设计模式——代理模式(Proxy)
- java设计-代理模式
- java设计模式——装饰者模式(代理模式)
- java设计模式----代理模式