• 设计模式-代理模式


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

    测试结果:

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

  • 相关阅读:
    C# 模拟浏览器请求
    关于获取时间后,时间格式为几天前,几小时前格式转化
    关于通用的C#后台获取前台页面的标签的正则表达式
    关于getHTML()方法和getHtmlAjax()方法 GetHttpLength, 清除HTML标签
    性能测试术语
    聚合报告中90% Line涉及到百分位数的概念
    使用Windows的cmd运行(或通过批处理启动)Python项目(多目录项目)提示找不到模块的解决办法
    OSError: [WinError 6] 句柄无效的解决办法
    python中日志输出重复的解决办法
    截图方法get_screenshot_as_file()注意点
  • 原文地址:https://www.cnblogs.com/yintingting/p/6872740.html
Copyright © 2020-2023  润新知