虚拟代理模式(Virtual Proxy)是一种节省内存的技术,它建议建立那些占用大量内存或处理复杂的对象时,把建立这类对象推迟到使用它的时候。在特定的应用中,不一样部分的功能由不一样的对象组成,应用启动的时候,不会当即使用全部的对象。在这种状况下,虚拟代理模式建议推迟对象的建立直到应用程序须要它为止。对象被应用第一次引用时建立而且同一个实例能够被重用。这种方法优缺点并存。html
优势:java
这种方法的优势是,在应用程序启动时,因为不须要建立和装载全部的对象,所以加速了应用程序的启动。程序员
缺点:面试
由于不能保证特定的应用程序对象被建立,在访问这个对象的任何地方,都须要检测确认它不是空(null)。也就是,这种检测的时间消耗是最大的缺点。ide
应用虚拟代理模式,须要设计一个与真实对象具备相同接口的单独对象(指虚拟代理)。不一样的客户对象能够在建立和使用真实对象地方用相应的虚拟对象来代替。虚拟对象把真实对象的引用做为它的实例变量维护。代理对象不要自动建立真实对象,当客户须要真实对象的服务时,调用虚拟代理对象上的方法,而且检测真实对象是否被建立。函数
若是真实对象已经建立,代理把调用转发给真实对象,若是真实对象没有被建立:工具
按照这种安排,验证对象存在和转发方法调用这些细节对于客户是不可见的。客户对象就像和真实对象同样与代理对象进行交互。所以客户从检测真实对象是否为null中解脱出来,另外,因为建立代理对象在时间和处理复杂度上要少于建立真实对象。所以,在应用程序启动的时候,用代理对象代替真实对象初始化。ui
例子:this
假设咱们创建一个JAVA程序的集成开发环境(Integrated Development Environment),这个环境包括三个功能:编译、运行、生成JavaDoc文档。在新建和编辑Java程序时,最为经常使用的是编译和运行。至于生成JavaDoc文档对于每个Java程序不是必需的。所以,在Java开发环境启动时,不要建立和装载实现集成开发环境所有功能的全部对象,仅建立那些在编辑、编译、运行时用到的对象,保留提供生成JavaDoc文档的对象,这是一个好的设计思想。这种对象建立策略可以高效地利用内存空间而且加快了集成开发环境的启动速度。spa
假设编译、运行、生成JavaDoc文档这些功能分别由三个工具类提供??Compiler、Runtime和JavaDoc。客户对象能够访问的不一样IDE操做的接口以抽象类IDEOperation的形式定义。
public abstract class IDEOperation { private Compiler cmp; private Runtime rtime; public void compile(String javaFile) { cmp.compile(javaFile); } public void run(String classFile) { rtime.run (classFile); } //to be delayed until needed. public abstract void generateDocs(String javaFile); public IDEOperation() { cmp = new Compiler(); rtime = new Runtime(); } }
类IDEOperation提供了编译、运行java程序方法的实现,做为它构造函数的一部分,IDEOperation建立和装载了进行编译和执行操做的Compiler和Runtime对象。生成JavaDoc文档的方法generateDocs方法被设计成抽象的方法,由它的子类来实现。
让咱们定义抽象类IDEOperation的一个具体子类RealProcessor。做为RealProcessor构造函数的一部分,建立JavaDoc对象来提供生成JavaDoc文档的服务,经过使用JavaDoc对象功能实现generateDocs方法。
public class RealProcessor extends IDEOperation { JavaDoc jdoc; public RealProcessor() { super(); jdoc = new JavaDoc(); } public void generateDocs(String javaFile) { jdoc.generateDocs(javaFile); } }
经过上面的实现,RealProcessor类包含了编译、运行和生成JavaDoc文档的全部功能。像咱们原来讨论的,生成JavaDoc文档的功能不是每个Java程序所必须的,当RealProcessor实例化的时候,包括负责生成JavaDoc文档的JavaDoc对象的一系列对象被建立。推迟建立JavaDoc对象有如下优势:
在不改变RealProcessor实现的前提下,能够经过定义IDEOperation的另一个子类ProxyProcessor来实现虚拟代理。由于RealProcessor和ProxyProcessor共享相同的接口,客户对象能够用ProxyProcessor代替RealProcessor。图25.1展现了类层次;
public class ProxyProcessor extends IDEOperation { private RealProcessor realProcessor; public void generateDocs(String javaFile) { /* In order to generate javadocs the proxy loads the actual object and invokes its methods. */ if (realProcessor == null) { realProcessor = new RealProcessor(); } realProcessor.generateDocs(javaFile); } }
做为本身的实例变量,ProxyProcessor维护了RealProcessor对象的一个引用。做为generateDocs方法的一部分,ProxyProcessor检测引用变量是否被初始化为RealProcessor对象。若是没有被初始化,它建立一个RealProcessor对象并把这个对象分配给它的实例变量。一旦RealProcessor对象已经被建立,就调用其上的generateDocs方法。
实际上,也就是当客户对象第一次请求产生javadoc文档时,RealProcessor才被初始化装入内存中。反过来,直到客户须要为Java程序生成javadocs时,JavaDoc对象才会被建立和装入内存中。
客户对象像调用真实处理对象同样调用ProxyProcessor上的方法,并不须要关心(知道)RealProcessor对象是否存在。 至于验证、检测和ProxyProcessor和RealProcessor之间的交互、这样的细节对于客户对象是透明的。
public class Client { public static void main(String[] args) { /* At this point objects required for the compile and run operations are created, but not the objects that provide the generate Javadoc functionality. */ IDEOperation IDE = new ProxyProcessor(); IDE.compile("test.java"); IDE.run("test.class"); /* The Javadoc functionality is accessed For the first time and hence the Object offering the Javadoc generation Functionality is loaded at this point. */ IDE.generateDocs("test.java"); } }
【推荐阅读】
Java程序员备战“金九银十”必备的面试技巧(附携程Java岗面试题)
原文出处:https://www.cnblogs.com/Java-no-1/p/11347427.html