在某些情况下,我们希望通过一个中间代理来控制对某个对象的访问,这可能是因为原始对象的创建或访问涉及复杂的逻辑,或者我们想要在访问原始对象之前或之后执行一些操作
代理模式提供了一个代理对象,它充当了原始的对象的替代品,以控制对原始对象的访问。代理对象与原始对象实现相同的接口,使得客户端可以无缝的切换和使用。代理对象可以对客户端的请求进行拦截,修改或增强,然后将请求传递给原始对象。
代理模式的应用可以带来多种效果:
- 远程代理(Remote Proxy):代理对象可以隐藏原始对象存在于远程服务器上的事实,使得客户端可以透明的访问远程对象。这对于分布式系统非常有用。
- 虚拟代理(Virtual Proxy):当创建原始对象需要大量资源时,代理对象可以充当一个轻量级的替代品,延迟原始对象的实际创建和初始化,从而提高性能。
- 保护代理(Pr0tection Proxy):代理对象可以控制原始对象的访问权限,确保只有具有特定权限的客户端可以访问原始对象。
- 缓存代理(Cache Proxy):代理对象可以缓存原始对象的结果,以便在后续相同请求时能够直接返回缓存的结果,减少重复计算。
- 日志记录代理(Logging Proxy):代理对象可以在访问原始对象之间或者之后记录日志,用于调试,监控或审计。
代理模式允许我们在不改变原始对象的情况下,通过引入代理对象来添加额外的控制和功能,这有助于提高代码的可维护性、可扩展性和灵活性。
代码实例:
// 图像接口
interface Image {
void display();
}
// 真实图像类
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadImageFromDisk();
}
private void loadImageFromDisk() {
System.out.println("Loading image from disk: " + filename);
}
public void display() {
System.out.println("Displaying image: " + filename);
}
}
// 代理图像类
class ProxyImage implements Image {
private RealImage realImage;
private String filename;
public ProxyImage(String filename) {
this.filename = filename;
}
public void display() {
if (realImage == null) {
realImage = new RealImage(filename);
}
realImage.display();
}
}
// 在这个示例中,Image接口定义了display方法,RealImage是实际的图像加载类,而ProxyImage是代理图像类。
// 当ProxyImage的display方法被调用时,它会在需要时创建一个RealImage实例,并调用其display方法。
public class ProxyPatternExample {
public static void main(String[] args) {
Image image = new ProxyImage("sample.jpg");
// 图像未加载,直到调用display()方法
image.display();
// 图像已加载,无需再次创建
image.display();
}
}