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

    测试结果:

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

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 二元函数
    Java实现 蓝桥杯VIP 算法训练 二元函数
    Java实现 蓝桥杯VIP 算法训练 二元函数
    Java实现 蓝桥杯VIP 算法训练 二元函数
    Java实现 蓝桥杯VIP 算法训练 二元函数
    创建虚拟桌面的代码(重启桌面进程)(使用GetThreadDesktop,CreateDesktop,SetThreadDesktop等函数)
    SEH and C++ Exceptions,自定义CSeException
    VC自动与Internet时间服务器同步更新
    VS2005 检测内存泄漏的方法(转载)
    VC判断当前用户有无Administrator的权限(用EqualSid API函数判断与Admin是否在一个组的Sid)
  • 原文地址:https://www.cnblogs.com/yintingting/p/6872740.html
Copyright © 2011-2022 走看看