代理模式(Proxy Pattern)
代理模式是我们比较常用的设计模式之一。其中新思想是为了提供额外的处理或者不同的
操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信,代理模式一般涉及到的角色有:
抽象角色:声明真实对象和代理对象的共同接口;
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理
对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代
理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用。
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
上面这个例子,你就是“客户”,票务中心就是“代理角色”,火车站是“真实角色”,卖票称为“抽象角色”
//抽象角色:抽象类或接口
interface Business{
void doAction();
}
//真实角色:真正实现了业务逻辑接口
public BusinessImpl implements Business{
public void doAction(){
System.out.println("我是真实角色“);
}
}
class BusinessImplProxy implements Business
{
private BusinessImpl bi;
public void doAction()
{
if (bi==null)
{
bi = new BusinessImpl();
}
doBefore();
bi.doAction();
doAfter();
}
public void doBefore()
{
System.out.println("前置处理!");
}
public void doAfter()
{
System.out.println("后置处理!");
}
}
//测试类
class Test
{
public static void main(String[] args)
{
//引用变量定义为抽象角色类型
Business bi = new BusinessImplProxy();
bi.doAction();
}
}
最后符上一个动态代理的例子:
1. import java.lang.reflect.InvocationHandler;
2. import java.lang.reflect.Method;
3. import java.lang.reflect.Proxy;
4. //业务接口
5. interface HelloWorld{
6. void sayHelloWorld();
7. }
8. //业务实现
9. class HelloWorldImpl implements HelloWorld{
10. public void sayHelloWorld(){
11. System.out.println(" HelloWorld! ");
12. }
13. }
14. //InvocationHandler实现,需要在接口方法调用前后加入一部分处理工作。
15. import java.lang.reflect.InvocationHandler;
16. import java.lang.reflect.Method;
17. class HelloWorldHandler implements InvocationHandler {
18. private Object objOriginal;
19. /**
20. * 构造函数。
21. * @param obj 要代理的原始对象。
22. */
23. public HelloWorldHandler(Object obj) {
24. this.objOriginal = obj ;
25. }
26. public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
27. Object result ;
28. //方法调用之前
29. doBefore();
30. //调用原始对象的方法
31. result = method.invoke(this.objOriginal ,args);
32. //方法调用之后
33. doAfter();
34. return result ;
35. }
36. private void doBefore() {
37. System.out.println("before method invoke!");
38. }
39. private void doAfter() {
40. System.out.println("after method invoke!");
41. }
42. }
43. //测试代码
44. //import java.lang.reflect.InvocationHandler;
45. import java.lang.reflect.Proxy;
46. public class Test{
47. public static void main(String[] args){
48. //首先获取一个业务接口的实现对象
49. HelloWorld val = new HelloWorldImpl();
50. //获取一个InvocationHandler实现,这里是HelloWorldHandler对象
51. InvocationHandler handler = new HelloWorldHandler(val);
52. //创建动态代理对象
53. HelloWorld proxy =(HelloWorld)Proxy.newProxyInstance(val.getClass().getClassLoader(),val.getClass().getInterfaces(),handler);
54. //通过动态代理对象调用sayHelloWorld()方法,此时会在原始对象HelloWorldImpl. sayHelloWorld()方法前后输出两句字符串。
55. proxy.sayHelloWorld();
56. }
57. }