• 代理模式学习


    简介

    为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

    • 作用
      • 代理模式的作用是,为其他对象提供一种代理,在不改变接口的前提下,以控制对这个对象的访问
    • 角色
      • 代理模式一般涉及到3个角色:抽象角色(接口)、代理角色、被代理角色
    • 类型
      • 静态代理、动态代理(jdk代理、CGLIB代理)

    静态代理

    代理类、被代理类需要实现相同的接口,或者继承相同的父类

    • 接口

      package cn.proxy.statictest;
      
      public interface Person {
          void say();
      }
      
    • 被代理类

      package cn.proxy.statictest;
      
      public class Chirld implements Person {
          @Override
          public void say() {
              System.out.println("i am liangzilun");
          }
      }
      
    • 代理类

      package cn.proxy.statictest;
      
      public class ChirldProxy implements Person {
      
          private Person p;
      
          public ChirldProxy(Person p) {
              this.p = p;
          }
      
          @Override
          public void say() {
              System.out.println("i am heizi");
              p.say();
          }
      }
      
    • 测试类

      package cn.proxy.statictest;
      
      public class StaticProxyTest {
          public static void main(String[] args) {
      
              ChirldProxy chirldProxy = new ChirldProxy(new Chirld());
              chirldProxy.say();
          }
      }
      

    可以看到可以在不改变 被代理类的情况下,增加一些功能。

    • 缺陷
      • 被代理类须已经存在,而且作为代理类的内部属性
      • 每个业务类都要一个代理类,如果业务量庞大,会导致类急剧膨胀
      • 如果接口修改,代理类和被代理类也需要跟着修改,不易维护。

    动态代理(JDK代理)

    • 代理类是在程序运行期间由JVM根据反射等机制动态生成的。

    • 被代理类须实现接口

    • 接口类

      package cn.proxy.dynamicproxy;
      
      public interface Person {
          void say();
      }
      
    • 被代理类

      package cn.proxy.dynamicproxy;
      
      public class Chirld implements Person {
          @Override
          public void say() {
              System.out.println("i am liangzilun");
          }
      }
      
    • jdk代理

      package cn.proxy.dynamicproxy;
      
      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      import java.lang.reflect.Proxy;
      
      public class DynamicProxy implements InvocationHandler {
          private Object target;
      
          public DynamicProxy(Object target) {
              this.target = target;
          }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              System.out.println("i am heizi");
              method.invoke(target,args);
              return null;
          }
      
          // 返回动态代理 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
          public <T> T getProxy(){
              return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
          }
      }
      
    • 测试

      package cn.proxy.dynamicproxy;
      
      public class DynamicProxyTest {
          public static void main(String[] args) {
      
              DynamicProxy dynamicProxy = new DynamicProxy(new Chirld());
              Person proxy = dynamicProxy.getProxy();
              proxy.say();
          }
      }
      

    参考

  • 相关阅读:
    .net core 操作域控 活动目录 ladp -- Support for System.DirectoryServices for Windows
    运行在 Android 系统上的完整 Linux -- Termux
    Windows Python 版本切换工具 --- Switch Python Version Tool For Windows
    简单的NLog配置文件
    python之set基本使用
    复习PHP的数组
    php动态修改配置文件
    制作一个php万年历
    一个简单的选项卡
    python操作文件的笔记
  • 原文地址:https://www.cnblogs.com/depycode/p/13724414.html
Copyright © 2020-2023  润新知