zoukankan      html  css  js  c++  java
  • 结构型模式 -- 代理模式(静态代理&动态代理)

    静态代理:

      真实角色和代理角色实现相同的接口,代理角色拥有真实角色的引用。代理角色去执行方法,对于某些“真正”需要真实角色自己执行的方法时,在代理角色内部就调用真实角色的方法,其他的就可以执行代理角色的方法(例如房主和中介,有带领客户看房,签合同,交钱,收房等方法,那么签合同、交钱就是“真正”需要真实角色自己执行的方法,其他的方法就可以直接交给中介去执行)

     应用场景:

    1)安全代理:屏蔽对真实角色的直接访问

    2)延迟加载:先加载轻量级的代理对象,真正需要时再加载真实对象

    动态代理:

    实现方式有:JDK自带的动态代理;    javaassist字节码操作库实现;CGUB;ASM

    JDK自动的动态代理:

    代码实现:

    // 接口
    public interface IAccount {
        IAccount deposit(double money);
        double getBalance();
    }
    // 真实角色
    public class Account implements IAccount{
        private double balance = 100;
        @Override
        public IAccount deposit(double money) {
            balance += money;
            return null;
        }
        @Override
        public double getBalance() {
            return balance;
        }
    
    }
    // 处理器
    public class AccountHandler implements InvocationHandler{
        IAccount account;
        public AccountHandler(IAccount account) {
            this.account = account;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if("deposit".equals(method.getName())) {
                method.invoke(account, args);
                return proxy;
            }else {
                return method.invoke(account, args);
            }
        }
    
    }
    // 应用
    public class Client02 {
        public static void main(String[] args) {
            IAccount account = new Account();
            AccountHandler handler = new AccountHandler(account);
            IAccount proxy = (IAccount) Proxy.newProxyInstance(account.getClass().getClassLoader(), account.getClass().getInterfaces(), handler);
            IAccount proxy1 = proxy.deposit(100);
            double b = proxy.getBalance();
            System.out.println(b);
        }
    }

    结果:

    可以看到在处理器那个代码里面,invoke()里面的两处的返回有些不同,一般的就直接一句代码:return method.invoke(account, args)

    这里写这么多是为了体现 public Object invoke(Object proxy, Method method, Object[] args) 参数proxy 的作用:

    取至源码(对invoke()方法的说明):

    意思: 1:当一个方法在代理对象上被调用 will be(实际上是) 在 invocation handler上调用

                 2: method是在参数proxy 上被调用

    proxy  <-------> this

    // 将上面代码的应用部分改成:
    public class Client02 {
        public static void main(String[] args) {
            IAccount account = new Account();
            AccountHandler handler = new AccountHandler(account);
            IAccount proxy = (IAccount) Proxy.newProxyInstance(account.getClass().getClassLoader(), account.getClass().getInterfaces(), handler);
            proxy.deposit(100).deposit(200);
            double b = proxy.getBalance();
            System.out.println(b);
        }
    }

    结果:

    静态代理需要自定义代理对象,动态代理是动态生成代理对象

  • 相关阅读:
    Laravel框架中的event事件操作
    PHP魔术方法实例
    PHP 面向对象
    ThinkPHP中where()使用方法详解
    PHP常见错误提示含义解释
    php面向对象编程self和static的区别
    php文件路径获取文件名
    php三种无限分类
    php高精度计算问题
    转:JavaScript定时机制、以及浏览器渲染机制 浅谈
  • 原文地址:https://www.cnblogs.com/DDiamondd/p/10975671.html
Copyright © 2011-2022 走看看