Java设计模式笔记之代理模式
来源:互联网 发布:java 多泛型的 编辑:程序博客网 时间:2024/05/22 13:19
1.代理模式
代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
2.代理的种类
如果按照使用目的来划分,代理有以下几种:
(1)远程代理(Remote):为一个位于不同的地址空间的对象提供一个局域代表对象。
(2)虚拟代理(Virtual):根据需要创建一个资源消耗比较大的对象,使得此对象只在需要时才会被真正创建,之前使用的是代理。
(3)Copy-on-write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
(4)保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
(5)Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端乐意共享这些结果。
(6)防火墙(firewall)代理:保护目标,不让恶意用户接近。
(7)同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
(8)智能引用(Smart Referenc)代理:当一个对象被引用是,提供一些额外的操作。
3.代理模式的结构
类图:
抽象主题(Subject):定义了实际对象和代理对象的共同行为,使得能使用实际对象的地方都能使用代理。
代理主题(Proxy):代理类,持有一个被代理的类的引用,可以自由操作被代理对象;用户和被代理类相同的接口,在任何环境中都可以代替被代理类;控制对被代理对象的引用;在引用被代理对象的方法前或者后,一般会执行一些额外操作。
真实主题(RealSubject):被代理类。
4.示例源码
Subject.java
package com.patterns.proxy;abstract public class Subject{ abstract public void request();}
ProxySubject.java
package com.patterns.proxy;public class ProxySubject extends Subject { private RealSubject realSubject;public ProxySubject(){}public void request(){ preRequest();if( realSubject == null ) {realSubject = new RealSubject();} realSubject.request(); postRequest();} private void preRequest() { System.out.println("pre request from proxy"); } private void postRequest() { System.out.println("after requet from proxy"); }}
RealSubject.java
package com.patterns.proxy;public class RealSubject extends Subject {public RealSubject(){ }public void request(){ System.out.println("From real subject.");}}
Client.java
package com.patterns.proxy;public class Client{ private static Subject subject; static public void main(String[] args){ subject = new ProxySubject();subject.request();}}
运行结果:
pre request from proxy
From real subject.
after requet from proxy
代理调用时,在实际对象的调用的前后加入了一些自己的操作(智能引用)。
5.动态代理
在Java中,提供了支持代理模式的接口,可以在运行时间内创建代理对象。
package com.patterns.proxy.reflect;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.ArrayList;import java.util.List;/** * *与代理类相关联的InvocationHandler对象 * */public class ListProxy implements InvocationHandler{ private Object proxyobj; public ListProxy(Object obj) { proxyobj = obj; } /** *创建代理对象的工厂方法 * */public static Object factory(Object obj) {Class<?> cls = obj.getClass(); return Proxy.newProxyInstance( cls.getClassLoader(), cls.getInterfaces(),//指定被代理的接口函数 new ListProxy(obj) );//指定InvocationHandler }/** * 调用被代理的接口函数的处理,可以添加一些额外的操作 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("before calling " + method); if (args != null) {for (int i=0; i<args.length; i++) { System.out.println(args[i] + ""); }} Object o = method.invoke(proxyobj, args);System.out.println("after calling " + method); return o; } public static void main(String[] args) {List<String> v = null; v = (List<String>) factory(new ArrayList<String>()); v.add("New"); v.add("York"); }}
创建动态代理的过程
(1)指明一系列接口来创建代理对象,上例在工厂方法中指明使用传入参数的接口,如果没有接口的话,本例不适用。
(2)继承InvocationHandler实现一个代理处理器,在创建代理时使用,系统会把它和指定的接口做关联。
(3)invoke函数的改写,invoke函数会拦截被指定的接口,并执行自己的内容。
(4)在运行时,新建代理对象,并运行。
上例中运行结果:
before calling public abstract boolean java.util.List.add(java.lang.Object)
New
after calling public abstract boolean java.util.List.add(java.lang.Object)
before calling public abstract boolean java.util.List.add(java.lang.Object)
York
after calling public abstract boolean java.util.List.add(java.lang.Object)
拦截了被指定的List的接口,包括add();所以在 v.add("New"); v.add("York");时,其实是执行了ListProxy中的invoke的内容
- Java设计模式笔记之代理模式
- Java设计模式笔记之代理模式
- java设计模式学习笔记之代理模式
- Java设计模式之代理设计模式
- 设计模式学习笔记之代理模式
- 设计模式笔记之---代理模式
- 设计模式学习笔记之代理模式
- 设计模式之禅笔记-代理模式
- 设计模式之代理模式--慕课网笔记
- 设计模式笔记之代理模式
- java设计模式学习笔记--代理模式
- Java设计模式之代理
- Java设计模式之代理
- java设计模式之代理
- java之代理设计模式
- java之代理设计模式
- Java设计模式之代理模式
- Java设计模式之计数代理模式
- linux下的tomcat配置多域名网站
- poj 2406 Power Strings KMP应用
- svn中添加不想被提交的文件到ignore列表中
- 用ATL建立轻量级的COM对象(五)
- 对使用包(Package)的忠告
- Java设计模式笔记之代理模式
- ajax的同步与异步
- UIWebView显示PDF文件
- Java 访问权限修饰词(access specifier)
- 文档清单
- JFrame 和 Frame 小小的不同
- zip非暴力破解
- 用ATL建立轻量级的COM对象(六)
- 从业务角度分析android binder的使用