zoukankan      html  css  js  c++  java
  • 代理模式

    模式名和分类

    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代理会更好。

    相关模式

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

  • 相关阅读:
    进程
    并发编程
    操作系统的发展史
    __init__、__new__、__call__ 方法
    MongoDB文档操作
    MongoDB集合操作
    MongoDB数据库操作
    MongoDB连接
    MongoDB的文档存储结构
    MongoDB 概念
  • 原文地址:https://www.cnblogs.com/dhcao/p/11262459.html
Copyright © 2011-2022 走看看