代理模式(设计模式Java版本)

代理模式的定义

达到某个目标,通过代理或自己直接去做,都可以完成,但是通过代理可以给自己代理某种好处,比如:租房找中间可以节省时间找到自己满意的房子;购票找黄牛可以解决春节一票难求的窘境;

代理模式的分类
静态代理

代理类的代码都是提前写好的

/**
 * @author freedom
 */
public interface Buy {

  /**
   * 购买接口
   */
  void buy();
}

/**
 * @author :  freedom
 * @Description :  真正要买票的类
 * @Creation Date:  2019-10-27 9:59 下午
 */
public class BuyTrainTicket implements Buy {

  @Override
  public void buy() {
    System.out.println("我要购买一张从北京到上海的高铁票");
  }
}

/**
 * @author :  freedom
 * @Description :  代理买票的黄牛类
 * @Creation Date:  2019-10-27 10:03 下午
 */
public class BuyTrainTicketProxy implements Buy {

  private Buy buyTrainTicket;

  BuyTrainTicketProxy(Buy buy) {
    this.buyTrainTicket = buy;
  }

  @Override
  public void buy() {
    System.out.println("我帮你抢从北京到上海的票");
    System.out.println("我要收取50元的手续费");
    buyTrainTicket.buy();
    System.out.println("加个微信,下次买给你打八折");
  }
}


/**
 * @author :  freedom
 * @Description :  客户端测试类
 * @Creation Date:  2019-10-27 10:08 下午
 */
public class StaticProxyTest {

  public static void main(String[] args) {
    Buy buyTrainTicket = new BuyTrainTicket();
    BuyTrainTicketProxy buyTrainTicketProxy = new BuyTrainTicketProxy(buyTrainTicket);
    buyTrainTicketProxy.buy();
  }
}

运行结果:
我帮你抢从北京到上海的票
我要收取50元的手续费
我要购买一张从北京到上海的高铁票
加个微信,下次买给你打八折
动态代理

代理类的代码是通过java反射原理动态生成的

/**
 * @author freedom
 */
public interface Buy {

  /**
   * 购买接口
   */
  void buy();
}

package poxy;

/**
 * @author :  freedom
 * @Description :  真正要买票的类
 * @Creation Date:  2019-10-27 9:59 下午
 */
public class BuyTrainTicket implements Buy {

  @Override
  public void buy() {
    System.out.println("我要购买一张从北京到上海的高铁票");
  }
}

package poxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @author :  freedom
 * @Description :  实现了InvocationHandler的代理处理器
 * @Creation Date:  2019-10-28 6:50 上午
 */
public class DynamicTrainTicketHandler implements InvocationHandler {

  private Buy buyTrainTicket;

  DynamicTrainTicketHandler(Buy buy) {
    this.buyTrainTicket = buy;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("我帮你抢从北京到上海的票");
    System.out.println("我要收取50元的手续费");
    //执行真正想实现目标对象的某个方法
    method.invoke(buyTrainTicket, args);// java 反射 调用包装在当前Method对象中的方法。
    System.out.println("加个微信,下次买给你打八折");
    return null;
  }
}

package poxy;

import java.lang.reflect.Proxy;

/**
 * @author :  freedom
 * @Description :  动态代理客户端测试类
 * @Creation Date:  2019-10-28 6:54 上午
 */
public class DynamicProxyTest {

  public static void main(String[] args) {
    //保存动态代理生成的源码位于当前项目的com.sun.proxy.$Proxy0.class 下
    System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

    //创建一个真正想达成目标的对象
    Buy buyTrainTicket = new BuyTrainTicket();
    //创建一个代理对象处理器
    DynamicTrainTicketHandler dynamicTrainTicketHandler = new DynamicTrainTicketHandler(
        buyTrainTicket);
     //动态生成代理对象
    Buy buy = (Buy) Proxy.newProxyInstance(buyTrainTicket.getClass().getClassLoader(),
        buyTrainTicket.getClass().getInterfaces(), dynamicTrainTicketHandler);
    //调用代理对象的购买动作方法
    buy.buy();

  }
}

运行结果:
我帮你抢从北京到上海的票
我要收取50元的手续费
我要购买一张从北京到上海的高铁票
加个微信,下次买给你打八折

动态生成的源码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.sun.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import poxy.Buy;

public final class $Proxy0 extends Proxy implements Buy {
  private static Method m1;
  private static Method m2;
  private static Method m3;
  private static Method m0;

  public $Proxy0(InvocationHandler var1) throws  {
    super(var1);
  }

  public final boolean equals(Object var1) throws  {
    try {
      return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
    } catch (RuntimeException | Error var3) {
      throw var3;
    } catch (Throwable var4) {
      throw new UndeclaredThrowableException(var4);
    }
  }

  public final String toString() throws  {
    try {
      return (String)super.h.invoke(this, m2, (Object[])null);
    } catch (RuntimeException | Error var2) {
      throw var2;
    } catch (Throwable var3) {
      throw new UndeclaredThrowableException(var3);
    }
  }

  public final void buy() throws  {
    try {
      //调用InvocationHandler.invoke方法
      super.h.invoke(this, m3, (Object[])null);
    } catch (RuntimeException | Error var2) {
      throw var2;
    } catch (Throwable var3) {
      throw new UndeclaredThrowableException(var3);
    }
  }

  public final int hashCode() throws  {
    try {
      return (Integer)super.h.invoke(this, m0, (Object[])null);
    } catch (RuntimeException | Error var2) {
      throw var2;
    } catch (Throwable var3) {
      throw new UndeclaredThrowableException(var3);
    }
  }

  static {
    try {
      m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
      m2 = Class.forName("java.lang.Object").getMethod("toString");
      m3 = Class.forName("poxy.Buy").getMethod("buy");
      m0 = Class.forName("java.lang.Object").getMethod("hashCode");
    } catch (NoSuchMethodException var2) {
      throw new NoSuchMethodError(var2.getMessage());
    } catch (ClassNotFoundException var3) {
      throw new NoClassDefFoundError(var3.getMessage());
    }
  }
}


代理模式的使用场景
缓存代理

将经常访问的数据放到内存中,作为缓存去使用,加快程序的访问处理速度,减轻数据存储被频繁访问的压力。

授权代理

对老旧的业务系统添加授权认证,为了解耦耦合,增加一个授权代理即可。

远程代理

远程服务器配置高,性能强劲,网络延迟低,处理能力强,可以将本地复杂的业务逻辑交于远程服务器处理,减少对客户端的响应时间

虚实代理

网络服务为了显示多张高分辨的图片,以及为了处理高负载运算,使用虚代理呈现给客户端,当客户端正在去看时,再调用真实的对象去处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bigdatafreedom

你的鼓励奖是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值