简单的了解下代理模式
代理就是一个人或一个机构代表另一个人或者机构采取行动。在一些情况下,一个客户不想或不能够直
接引用对象,而代理对象可以在客户端和目标对象之间起到中介作用
代理模式包括远程代理,虚拟代理,copy-on-write代理,保护代理,catch代理,防火墙代理,同步化
代理,只能引用代理,这些我就不一一介绍,我只是用简单例子,了解什么是代理模式。
代理模式设计到的角色:
抽象主题角色:声明了真是主题和代理主题的公共接口,这样可以使用真实主题的地方都可以使用代理
主题。
代理主题角色:代理主题角色内不含有真实主题的引用,从而可以在任何时刻操作真实主题对象,代理
主题角色提供一个与真实主题相同的接口,可以在任何时刻替代真实主题控制真实主题引用,负责在需要的
时候创建真实主题对象(和删除真实主题对象),代理角色通常再将客户端调用传递给真实主题之前,或之
后,都执行谋个操作,而不是单纯的将调用传递给真实主题。
真实主题角色:定义了代理角色所代表的真实对象
根据例子看看:
1. abstract public class Subject {
2. //定义抽象请求方法
3. abstract public void request();
4. }
真实主题
1. public class RealSubject extends Subject{
2.
3. public RealSubject(){
4.
5. }
6. public void request() {
7. // TODO Auto-generated method stub
8. System.out.println("请求");
9. }
10.
11. }
代理主题
1. public class ProxySubject extends Subject{
2.
3. private RealSubject realSubject;
4. public ProxySubject(){
5. System.out.println("进入代理类.......");
6. }
7. @Override
8. public void request() {
9. // TODO Auto-generated method stub
10. preRequest();
11. if(realSubject==null){
12. realSubject = new RealSubject();
13. }
14. realSubject.request();
15. postRequest();
16. }
17. /**
18. * 请求前操作
19. * */
20. private void preRequest(){
21. System.out.println("请求前");
22. }
23. /**
24. * 请求后操作
25. * */
26. private void postRequest(){
27. System.out.println("请求后");
28. }
29.
30. }
测试代理
1. public class TestProxy {
2. public static void main(String[] args) {
3. Subject s = new ProxySubject();
4. s.request();
5. }
6.
7. }
从这个测试不难看出代理类的作用,代理主题并不改变主题接口,模式的用意是不让客户端感觉到代理
的存在,其次,代理使用委派将客户端的调用委派给真实主题对象,代理主题起到的是一个传递作用;最
后,代理主题在传递请求之前和之后都可以执行特定的操作,而不是单纯的传递请求。
接下来说说动态代理模式
1. public class VectorProxy implements InvocationHandler{
2.
3. private Object proxyobj;
4.
5. public VectorProxy(Object obj){
6. proxyobj = obj;
7. }
8.
9. public static Object factory(Object obj){
10. Class cls = obj.getClass();
11. return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new VectorProxy(obj));
12.
13. }
14. /**
15. * 调用某个方法
16. * */
17. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
18. System.out.println("before calling"+method);
19. if(args!=null){
20. for(int i=0;i<args.length;i++){
21. System.out.println(args[i]);
22. }
23. }
24. Object o = method.invoke(proxyobj, args);
25. System.out.println("after calling"+method);
26. return o;
27.
28. }
29.
30. public static void main(String[] args){
31. List<String> v = null;
32. v = (List) VectorProxy.factory(new Vector(10));
33. v.add("New");
34. v.add("York");
35. }
36. }
运行结果:
before callingpublic abstract boolean java.util.List.add(java.lang.Object)
New
after callingpublic abstract boolean java.util.List.add(java.lang.Object)
before callingpublic abstract boolean java.util.List.add(java.lang.Object)
York
after callingpublic abstract boolean java.util.List.add(java.lang.Object)
此例子用了反射,从结果可以看出代理对象截获了对Vector对象的所有调用,在调用传递给Vector之前
和之后,代理对象具有采取合适操作的灵活性,虽然这里代理对象所采取的操作就是打印,也可以定义
其他操作。