lilele200706

 

代理模式

代理模式(以租房为例)

  1. 代理模式主要有四个对象

    • 抽象类(需要代理的事务)(租房)

    • 被代理对象(房东)

    • 代理对象(中介)

    • 客户(租房子的人)

什么是代理模式

为其他对象提供一种代理以控制对这个对象的访问。

代理模式的作用

扩展新功能时,可以避免在被代理对象中硬编码。

被代理对象的正在执行的方法前,可能需要增加参数的校验逻辑,或者打印日志的逻辑;在执行完方法后,可能需要统计执行的时间,触发结束的事件等等逻辑。此时,如果在代理对象里动态地添加此类逻辑,就避免了在被代理对象中硬编码。

怎么使用

一、静态代理

  1. 抽象类

public interface Rent {
   void rent();
}
  1. 被代理对象

public class Host implements Rent{
   public void rent() {
       System.out.println("我要出租房子。");
  }
}
  1. 代理对象(中介一般会有一些附属操作)

public class Proxy implements Rent{
   private Host host;
   public Proxy(Host host){
       this.host = host;
  }

   public void rent() {
       seeHouse();
       host.rent();
       hetong();
       fare();
  }

   public void seeHouse(){
       System.out.println("带你看房子");
  }

   public void hetong(){
       System.out.println("签租赁合同");
  }

   public void fare(){
       System.out.println("收中介费");
  }
}
  1. 客户

//我要看房子,租房子
public class Client {
   public static void main(String[] args) {
       Host host = new Host();
//       host.rent(); //只能租房子,不能看房子
       Proxy proxy = new Proxy(host);
      proxy.rent();

  }
}

缺点: 一个真实的角色就会产生一个代理角色,代码量会翻倍。

好处: 可以使我们的真实角色更加纯粹,不用再关心公共的业务。

  • 公共的业务有代理类来完成,实现业务的分工。

  • 公共业务发生扩展时,变得更加集中和方便

我们既想要静态代理的好处,又不想要它的坏处,所以研究出了动态代理。

二、动态代理(底层都是反射)

  1. 抽象角色(同上)

  2. 被代理角色(同上)

  3. 生成代理角色

//生成代理角色
public class ProxyInvocationHandler implements InvocationHandler {
   //接口
   //error:Host host;
   private Rent rent;

   public void setRent(Rent rent) {
       this.rent = rent;
  }

   //原代理角色的方法
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       //被代理角色的方法
       //error:method.invoke(proxy,args);
       return method.invoke(rent,args);
  }

   Proxy getProxy(){
       return (Proxy)Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
  }
}
  1. 客户

public class Client {
   public static void main(String[] args) {
       Host host = new Host();
       ProxyInvocationHandler pih = new ProxyInvocationHandler();
       pih.setRent(host);
       //error.pih.getProxy(host);
       Rent proxy = (Rent) pih.getProxy();
//error:proxy.invoke(host);
       proxy.rent();
  }
}

 

 

posted on 2021-12-23 11:44  lilele200706  阅读(27)  评论(0编辑  收藏  举报

导航