代理模式

模式名和分类

Proxy

意图

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

动机

1、在实际处理方不方便或者不适合直接出现时,使用代理来响应调用方。远程代理,虚拟代理,
2、主要目的是控制对象的访问,也可以做一定的增强或者和扩展。(spring的aop)

结构

参与者

  • 公共接口或者父类 -- Subject
  • 实际执行者 -- RealSubject
  • 代理执行者 -- Proxy

协作

  • 代理类Proxy实现公共接口(或者继承父类),拥有了跟实际执行者一样的方法入口。
  • Proxy内部聚合实际执行者 RealSubject
  • Proxy在公共方法中,实际使用realSubject来执行方法。

代码实例

https://www.runoob.com/design-pattern/proxy-pattern.html

// 步骤1
// 创建一个接口。Image.java
public interface Image {
   void display();
}

// 步骤 2
// 创建实现接口的实体类。RealImage.java
public class RealImage implements Image {
 
   private String fileName;
 
   public RealImage(String fileName){
      this.fileName = fileName;
      loadFromDisk(fileName);
   }
 
   @Override
   public void display() {
      System.out.println("Displaying " + fileName);
   }
 
   private void loadFromDisk(String fileName){
      System.out.println("Loading " + fileName);
   }
}

// ProxyImage.java
public class ProxyImage implements Image{
 
   private RealImage realImage;
   private String fileName;
 
   public ProxyImage(String fileName){
      this.fileName = fileName;
   }
 
   @Override
   public void display() {
      if(realImage == null){
         realImage = new RealImage(fileName);
      }
      realImage.display();
   }
}

// 步骤 3
// 当被请求时,使用 ProxyImage 来获取 RealImage 类的对象。ProxyPatternDemo.java
public class ProxyPatternDemo {
   
   public static void main(String[] args) {
      Image image = new ProxyImage("test_10mb.jpg");
 
      // 图像将从磁盘加载
      image.display(); 
      System.out.println("");
      // 图像不需要从磁盘加载
      image.display();  
   }
}

//步骤 4
//执行程序,输出结果:

> Loading test_10mb.jpg
> Displaying test_10mb.jpg
> Displaying test_10mb.jpg

已知应用

springAOP动态代理:

  • jdk代理:不论是动态还是静态代理,jdk的代理模式,都是通过接口来创建实现类作为代理。jdk只提供接口的代理,而不提供类的代理
  • cglib代理:cglib字节码技术生成的代理,它是通过创建子类来实现代理,正因为如此,所以cglib不能为final和private方法创建代理。

jdk代理在执行性能上远不如cglib动态代理。在高版本的spring中,jdk虽然有优化,但还是不足以跟cglib相提并论。但是!cglib在创建代理对象的过程中,所花费的时间远大于jdk代理。所以:jdk动态代理创建代理对象时比cglib创建对象性能好得多,但是jdk动态代理在执行代理方法时比cglib执行方法时性能差得多。这意味着,如果是单例,因为只需要创建一次代理,使用cglib好得多。如果不是单例,即需要频繁创建代理对象时,使用jdk代理会更好。

相关模式

可以跟适配器模式对比,都是代理执行,但是适配器模式的目的,是为了适配,着重点在于功能的修饰。而代理模式,主要目的是控制对象的访问

posted @ 2019-07-29 10:27  undifinedException  阅读(163)  评论(0编辑  收藏  举报