代理模式(基于接口)

来源:互联网 发布:比价软件bibijing 编辑:程序博客网 时间:2024/05/16 07:35
一、代理模式简介
代理模式的作用是:为其他对象提供一种代理,以控制对该对象的访问。在某种情况下,一个客户不想或者不能直接引用另一个对象,此时代理对象可以在客户端 和目标对象之间起到中介的作用。代理模式有如下特点:

职责清晰:真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
代理对象:可以在客户端和目标对象之前起到中介的作用,这样保护了目标对象
高扩展性
  代理模式UML图如下:



二、代理模式实现

  代理模式一般涉及到的角色如下:

抽象角色:声明真实对象和代理对象的共同接口
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象
  我们使用到JDK提供的代理类来实现动态代理。
1、创建Subject接口(抽象角色)
 package com.test.dynamicproxy; public interface Subject {     public void request();}


2、创建RealSubject类(真实角色)
package com.test.dynamicproxy;public class RealSubject implements Subject{    public void request()    {        System.out.println("From real subject!");    }}


3、创建DynamicSubject(该类用于产生代理对象)
package com.test.dynamicproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象 * 此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要 * 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后 加入自己的一些额外方法。 *  */public class DynamicSubject implements InvocationHandler {    private Object target;    public Object bind(Object target) {        this.target = target;        //返回代理对象        return Proxy.newProxyInstance(target                .getClassLoader(), target.getClass().getInterfaces(),                this);    }        /**     *@param proxy 代理对象     *      *@param method 要代理的方法     *     *@param args 该方法的参数对象数组     *     *@return     */    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        System.out.println("before calling: " + method);        //返回值        Object result = null ;        result = method.invoke(target, args);// 调用真实对象的方法,通过反射来调用        System.out.println("after calling: " + method);        return result ;    }     }


4、调用类Client

package com.test.dynamicproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class Client {    public static void main(String[] args) {        // 创建真实对象       InvocationHandler proxy  = new DynamicSubject();               Subject subject = (Subject)proxy.bind(new RealSubject());    }}