zoukankan      html  css  js  c++  java
  • 设计模式-代理模式

    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();
        }
    }

    测试结果:

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

  • 相关阅读:
    CentOS虚拟机和物理机共享文件夹实现
    集训第六周 数学概念与方法 概率 数论 最大公约数 G题
    集训第六周 数学概念与方法 概率 F题
    集训第六周 E题
    集训第六周 古典概型 期望 D题 Discovering Gold 期望
    集训第六周 古典概型 期望 C题
    集训第六周 数学概念与方法 UVA 11181 条件概率
    集训第六周 数学概念与方法 UVA 11722 几何概型
    DAG模型(矩形嵌套)
    集训第五周 动态规划 K题 背包
  • 原文地址:https://www.cnblogs.com/yintingting/p/6872740.html
Copyright © 2011-2022 走看看