设计模式-代理模式

1. 代理模式的作用

  将主要业务与次要业务进行松耦合组装。

2. 代理模式的本质

  监控行为特征

3. 案例

  (1)喝果粒果汁

    主要业务:喝果汁

    次要业务:喝前摇一摇

  (2)JDK代理模式实现

    接口:定义所有需要被监听行为

    接口实现类:农夫果粒,果粒橙

    通知类:实现次要业务,当前被拦截的主要业务与次要业务如何绑定执行

    代理对象

  示例:

  (1)创建接口

/*
 * 
 * 只有需要被监控的行为才有资格
 * 在这里声明 
 * 
 */
public interface DrinkService {
     public void drink();
}

 (2)接口实现类

public class Huiyuan implements DrinkService {
    @Override
    public void drink() {
        System.out.println("喝汇源果汁");
    }
}
public class Guolicheng implements DrinkService {
    @Override
    public void drink() {
        System.out.println("喝果粒橙");
    }
}

 (3)通知类

public class GuozhiInvocationHandler implements InvocationHandler {

    private DrinkService target;

    public GuozhiInvocationHandler(DrinkService target){
        this.target = target;
    }

//    invoke方法:在被监控行为将要执行时,会被JVM拦截,被监控行为和行为实现方会被作为参数输送invoke
//               这个被拦截方法是如何与当前次要业务方法绑定实现
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object returnValue = null;

        if("drink".equals(method.getName())){
            yaoyiyao();
           returnValue = method.invoke(target,args);
        }

        return returnValue;
    }

    private void yaoyiyao(){
        System.out.println("喝前摇一摇");
    }
}

  (4)代理类

public class ProxyFactory {

    public static DrinkService builder(Class clazz) throws IllegalAccessException, InstantiationException {

        //1.创建被监控实例对象
        DrinkService target = (DrinkService) clazz.newInstance();
        //2.创建一个通知对象
        InvocationHandler adviser = new GuozhiInvocationHandler(target);
        //3.向JVM申请负责监控target对象指定行为的监控对象(代理对象)
        /*
         *  loader:被监控对象隶属的类文件在内存中真实地址
         *  interfaces:被监控对象隶属的类文件实现接口
         *  h:监控对象发现小明要执行被监控行为,应该有哪一个通知对象进行辅助
         */
        DrinkService $proxy = (DrinkService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),adviser);
        return $proxy;
    }
}

测试类:

public class TestDemo {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {

        DrinkService huiyuan = ProxyFactory.builder(Huiyuan.class);
        huiyuan.drink();
        DrinkService guolicheng = ProxyFactory.builder(Guolicheng.class);
        guolicheng.drink();
    }
}

测试结果:

喝前摇一摇
喝汇源果汁
喝前摇一摇
喝果粒橙

原文地址:https://www.cnblogs.com/yintingting/p/6872740.html