设计模式之动态代理

解决问题

将【次要业务】和【主要业务】解耦合

代理模式

  1. 【次要业务】:起到辅助功能,辅助【主要业务】顺利实现。在项目 【次要业务】往往大量重复出现
  2. 【主要业务】:主要任务。
  3. 代理模式本质:行为的监听,对某个对象的某些方法调用的监听,
  4. 代理模式的组成
    1)接口:声明需要被监听行为
    2)代理实现类:(实现了InvocationHandler):次要业务的实现,次要业务和主要业务的绑定行为
    3)代理对象:监听的对象

业务代码

饭前便后洗手,主要业务:吃饭,上厕所。次要业务:洗手。
从以下代码中可以看到

  1. 声明需要被监听的方法

  2. 完成实现类,只需要负责主要业务(被监听的任务),并不需要负责次要业务。

  3. 创建一个代理实现类,当代理对象(ProxyFactory的newInstance返回的对对象)调用相应方法时(其本身不具有方法实现),那么就会调用代理实现类其中的invoke方法

  4. 在代理实现类中,需要得到一个被调用的实现类的对象,以便通过反射机制调用method.invoke(obj,args);其中被调用的实现类的对象在ProxyFactory会动态生成实现类对象。

  5. ProxyFactory, 动态生成实现类对象,将实现类对象赋值给代理Agent,以便agent调用。生成的代理对象,其不是接口实现类。当代理对象被调用时,会调用agent的invoke方法

/**
 * 声明需要被监听的方法
 */
public interface BaseInterface {

    void eating(String food);
    void wcing();

}
/**
 * 只需要负责主要业务,并不需要负责次要业务
 *
 */
public class Person implements BaseInterface {
    @Override
    public void eating(String food) {
        System.out.println("吃"+food);
    }

    @Override
    public void wcing() {
        System.out.println("wc");
    }
}
/**
 * 创建代理实现类
 *
 */
public class Agent implements InvocationHandler {

    /**
     *  被开发人员索要的真实对象
     */
    private BaseInterface obj;

    public Agent(BaseInterface obj) {
        this.obj = obj;
    }

    /**
     * 完成次要业务与主要业务的绑定
     *
     * @param proxy  本次负责监听的对象(不是执行对象)
     * @param method 被拦截的主要业务方法
     * @param args   被拦截的主要业务方法接收的实参
     * @return 返回method.invoke(obj,args);的返回对象
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object object = null;
        //1.读取被拦截方法的名称
        String methodName = method.getName();
        if ("eating".equals(methodName)) {
            wash();
            object = method.invoke(obj,args);
        } else if ("wcing".equals(methodName)) {
            object =method.invoke(obj,args);
            wash();
        }
        return object;
    }

    /**
     * 次要业务
     */
    private void wash() {
        System.out.println("洗手");
    }
}
/**
 * 完成代理实现类与借口呢实现类绑定
 */
public class ProxyFactory {
    /**
     * 动态创建一个对象,实现代理的创建,
     * 生成监听对象
     *
     * @param classFile 动态创建一个对象
     * @return 监听对象
     */
    public static BaseInterface newInstance(Class classFile) throws IllegalAccessException, InstantiationException {

        //动态创建一个对象
        BaseInterface p = (BaseInterface)classFile.newInstance();

        //拥有一个实现类对象,将动态对象封装起来
        InvocationHandler agent = new Agent(p);

        /*
          loader 指向被监控的类加载器在内存中的真实地址
          Interface:被监控的类的方法。就是需要被监控的行为
          agent:代理对象

         */
        Class[] classArray = {BaseInterface.class};

        //生成的代理对象,其不是BaseInterface的实现类
        BaseInterface baseInterface = (BaseInterface)Proxy.newProxyInstance(classFile.getClassLoader(),classArray,agent);

        return  baseInterface;
    }
}

你可能感兴趣的:(设计模式)