结构型-代理模式

来源:互联网 发布:美工助理的工作内容 编辑:程序博客网 时间:2024/05/22 15:50
package proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * @author jiq * 类型:Structural * 定义: 代理模式为另一个对象提供一个占位符(替身)以控制这个对象的访问。 * 话句话说,使用代理对象,可以让代理对象控制对某个对象的访问,被代理 * 的对象可以是远程对象,创建开销大的对象,或需要安全控制的对象。 *  * 为什么要控制访问:代理模式之所以要控制访问,是因为我们的客户不知道如何同 * 远程对象(被代理的对象)沟通。 比如远程代理访问,其帮助我们处理一些网络 * 上的细节。 * * 区别: 装饰器模式包装一个对象,并提供额外的行为。 *   适配器模式包装一个对象,并转换成不同的接口(接口改变)。 *   外观模式包装许多对象,以简化他们的接口(接口改变)。 *   代理模式包装一个对象,并控制它的访问(不改变被代理对象的接口)。 * 其实虽然从结构上来看和Decorator模式类似,但Proxy是控制,更像是一种对功能的限制, * 而Decorator是增加职责。  *  * 应用: Spring AOP的核心设计思想。 Java RMI(远程方法调用) *  * 代码说明:由于一些特殊原因,客户端无法直接访问真正的主题(比如网络问题,并发换环境等)。 * 这个时候我们通过一个代理来控制对真正主题的访问,比如远程代理会帮忙处理一些网络上 * 的细节,多线程环境下的代理会帮忙解决一些同步问题等。 然后客户端通过代理来访问对象。 */interface Subject{public void request();}/** * 真正的角色,实现了request方法 * */class RealSubject implements Subject{public void request(){System.out.print("real request handling\n");}}/************************************************ * 静态代理,封装(控制)request方法的访问  ************************************************/class StaticProxySubject implements Subject{private RealSubject realSubject;//组合被代理的对象public void request(){//do some thing else...if(realSubject == null){realSubject = new RealSubject();}realSubject.request();//真正的request调用//do some thing else...}}/*********************************************************** * 动态代理. java.lang.reflect包中有自己的代理支持,利用这个包 * 你可以在运行时动态创建一个代理类,实现一个或者多个接口,并将 * 方法的调用转发到你所指定的类。  * 因为实际的代理类是在运行时创建的,所以我们称这个技术为动态代理。 * ***********************************************************/class DynamicProxySubject implements InvocationHandler{private Object realSubject;//组合被代理的对象public DynamicProxySubject(Object realSubject){this.realSubject = realSubject;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//do some thing else...return method.invoke(realSubject, args);//do some thing else...}}/************************************************** * 客户端,代理ProxySubject控制其对RealSubject的访问 * ************************************************/public class ProxyTest {public static void main(String[] args) {//通过静态代理来访问对象Subject proxy = new StaticProxySubject();proxy.request();//通过动态代理来访问对象RealSubject real = new RealSubject();Subject subject = (Subject) Proxy.newProxyInstance(real.getClass().getClassLoader(), //定义代理类的类加载器 real.getClass().getInterfaces(),//代理类要实现的接口列表new DynamicProxySubject(real));//指派方法调用的调用处理程序subject.request();}}

原创粉丝点击