类型:结构型模式
实现原理:创建具有现有对象的对象
作用:为其他对象提供一种代理以控制对这个对象的访问。
解决的问题:由于对象的访问条件不一,直接访问对象会造成麻烦问题
解决问题的方法:增加中间层。
何时使用:想在访问一个类时做一些控制。
实现核心:实现与被代理类组合。
应用实例:Windows 里面的快捷方式
优点:1、分工明确。 2、易扩展
缺点:有些代理模式的实现非常复杂、有些代理模式可能会造成请求的处理速度变慢
使用场景:按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。
注意事项:
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
实现
步骤 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);}@Overridepublic 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;}@Overridepublic 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.jpgDisplaying test_10mb.jpg这段代码展示了代理模式的实现。下面对代码进行解释:步骤1:定义了一个Image接口,其中包含了一个display()方法。步骤2:创建了两个类,RealImage和ProxyImage,都实现了Image接口。RealImage类负责实际加载和显示图片,它接收一个文件名作为参数,在构造函数中从磁盘加载图片,并通过display()方法来显示图片。loadFromDisk()方法用于模拟从磁盘加载图片的过程。ProxyImage类充当了RealImage的代理类,它也实现了Image接口。ProxyImage类包含了一个RealImage对象和一个文件名。在调用display()方法时,如果realImage对象为空,表示图片尚未加载,则实例化一个RealImage对象并加载图片;然后调用realImage的display()方法显示图片。步骤3:在主程序ProxyPatternDemo中,创建了一个ProxyImage对象,并传入一个测试用的图片文件名。然后通过调用image.display()来显示图片。步骤4:执行程序,输出结果。第一次调用display()方法时,由于RealImage对象为空,会先进行加载图片的操作,然后显示图片。第二次调用display()方法时,由于RealImage对象已经存在,不再需要重新加载图片,直接显示即可。这个例子说明了代理模式的用途。在图片加载的过程中,由于加载大图可能比较耗时,所以可以使用代理模式来延迟加载图片,只有在需要显示图片时才加载。这样能够提高程序的性能和响应速度。```