美文网首页
chapter11_控制对象访问——代理模式

chapter11_控制对象访问——代理模式

作者: 米都都 | 来源:发表于2019-01-07 18:54 被阅读0次
  • 代理: 控制和管理访问

  • 远程代理

    (1) 在两个JVM中, 一个监视器想要远程调用另一个JVM上的对象, 那它先调用本地JVM的一个代理对象, 然后由代理对象处理所有网络通信的底层细节, 从而调用远程JVM上的对象

    (2) headfirst.designpatterns.proxy.gumball中的使用RMI的示例没有测试通过

  • 代理模式

    为另一个对象提供一个替身或占位符, 以控制这个对象的访问

    远程代理控制访问远程对象

    虚拟代理控制访问创建开销大的资源

    保护代理控制访问资源的权限

  • 虚拟代理

    (1) 作为创建开销大的对象的代表, 直到真正需要一个对象的时候再创建这个对象. 在创建前和创建中时, 由虚拟代理来扮演对象的替身

    (2) 示例: 网络加载显示图片, 加载成功前用"请等待"字样代替

      class ImageProxy implements Icon {
    
          ...
    
          private volatile ImageIcon imageIcon;
          private final URL imageURL;
          private boolean retrieving = false;
    
          public void paintIcon(final Component c, Graphics g, int x, int y) {
    
              if (imageIcon != null) {
                  imageIcon.paintIcon(c, g, x, y);
              } else {
    
                  g.drawString("Loading CD cover, please wait...", x + 300, y + 190);
    
                  if (!retrieving) {
    
                      retrieving = true;
    
                      Thread retrievalThread = new Thread(new Runnable() {
    
                          public void run() {
    
                              try {
                                  setImageIcon(new ImageIcon(imageURL, "CD Cover"));
                                  c.repaint();
                              } catch (Exception e) {
                                  e.printStackTrace();
                              }
                          }
                      });
    
                      retrievalThread.start();
                  }
              }
          }
    
          ...
      }
    
  • 代理模式和装饰器模式的区别

    意图不同: 装饰者为对象增加行为, 代理控制对象的访问

    另外, 装饰器可能包装很多层, 代理一般只包了一层

  • 代理模式和适配器模式的区别

    适配器模式会改变接口类型, 代理模式实现相同的接口

  • 如何强制客户使用代理而不是使用真正的对象?

    工厂方法

  • 保护代理

    (1) 保护代理的作用是控制权限, 由外面包的一层代理决定对内部对象的访问是否合法

    (2) Java中利用反射支持动态的代理(所以叫动态代理), 在java.lang.reflect中

    (3) 示例

    PersonBean.java

      public interface PersonBean {
    
          String getName();
    
          String getGender();
    
          ...
    
          void setName(String name);
    
          void setGender(String gender);
    
          ...
    
          void setHotOrNotRating(int rating);
      }
    

    PersonBean是一个接口, 它提供了一系列的get/set方法, 但是PersonBean的实例对象有时需要加一层代理, 由代理来决定哪些方法可以被访问, 哪些不可以

    TestProxy.java

      public class TestProxy {
    
          ...
    
          public void drive() {
    
              PersonBean joe = getPersonFromDatabase("Joe Javabean");
              PersonBean ownerProxy = getOwnerProxy(joe);
    
              ...
          }
    
          PersonBean getOwnerProxy(PersonBean person) {
    
              return (PersonBean) Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), new OwnerInvocationHandler(person));
          }
    
          ...
      }
    

    TestProxy是一个测试类, 在drive()方法中先创建了一个PersonBean对象joe, 但是joe的所有方法不应该全部被访问, 因此要得到joe的一个代理;

    这里使用了java.lang.Proxy中的静态方法newProxyInstance

      public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
    

    Proxy就是PersonBean对象的代理, 但是当代理的方法被调用时, 内部其实会调用InvocationHandler对象的invoke()方法;

    所以Proxy其实只是一个壳子, 重点要看InvocationHandler的实现类对象

    OwnerInvocationHandler.java

      public class OwnerInvocationHandler implements InvocationHandler {
    
          private PersonBean person;
    
          public OwnerInvocationHandler(PersonBean person) {
    
              this.person = person;
          }
    
          public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException {
    
              try {
    
                  if (method.getName().startsWith("get")) {
                      return method.invoke(person, args);
                  } else if (method.getName().equals("setHotOrNotRating")) {
                      throw new IllegalAccessException();
                  } else if (method.getName().startsWith("set")) {
                      return method.invoke(person, args);
                  }
    
              } catch (InvocationTargetException e) {
                  e.printStackTrace();
              }
    
              return null;
          }
      }
    

    OwnerInvocationHandler实现了InvocationHandler接口的invoke方法。 无论代理被调用的是什么方法, 最终一定会调用invoke();

    Method是一个反射类, 可以获取到代理被调用的方法, 从而做出响应的选择

相关文章

  • chapter11_控制对象访问——代理模式

    代理: 控制和管理访问 远程代理(1) 在两个JVM中, 一个监视器想要远程调用另一个JVM上的对象, 那它先调用...

  • 代理模式(Proxy Pattern)

    代理模式, 委托模式 意图:为其他对象提供一种代理以控制对这个对象的访问。 访问控制,而非加强功能。 代理:指具有...

  • 设计模式之代理模式

    定义 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。代理模式使得代理对象控制具体对象的引用...

  • 代理模式

    代理模式 代理模式定义,为另外一个对象提供一个替身以控制对这个对象的访问,是一个控制对象访问的模式。常用的几种控制...

  • 设计模式之——代理模式

    1 代理模式的定义 代理模式:代理模式又叫委托模式,是为某个对象提供一个代理对象,并且由代理对象控制对原对象的访问...

  • 深入理解Java动态代理

    代理模式 使用代理模式创建代理对象,让代理对象来控制对某个对象的访问, 被代理对象可以是远程对象,创建开销大的对象...

  • APP开发实战47-设计模式介绍5

    13.3.12代理模式 代理模式为其他对象提供一个代理以控制对这个对象的访问。 当无法或不想直接访问某个对象或访问...

  • GOF23设计模式day87:结构型模式和行为型模式

    一、结构模式 1.代理模式: 通过代理,控制对对象的访问;可以详细控制访问某个(某类)对象的方法,在调用这个方法前...

  • 代理模式-静态代理-动态代理-详解

    代理模式定义: 为其他对象提供代理,控制这个对象的访问。 代理模式角色定义 目标接口 目标对象    特点:实现目...

  • 代理模式

    代理模式 代理模式也叫做委托模式。 定义:为其他对象提供一种代理以控制对这个对象的访问。

网友评论

      本文标题:chapter11_控制对象访问——代理模式

      本文链接:https://www.haomeiwen.com/subject/esrprqtx.html