在现实生活中,我们经常使用代理来处理我们不想直接参与或无法直接参与的事务,例如,使用律师来代表法庭上的案件。在软件开发中,这种代理概念同样存在,被称为代理模式。代理模式允许我们通过创建一个替代对象(代理),来控制对其他对象的访问。这种模式在需要控制或增强对对象的访问时非常有用。
代理模式(Proxy Pattern)是一种结构型设计模式,它通过提供一个替代对象(代理)来代表真实对象的操作。代理控制对原始对象的访问,可以在访问对象时添加一些附加操作,例如访问控制、延迟初始化、日志等。
实现代理模式通常涉及以下几个关键组件:
代理模式适用于以下场景:
例如:
Spring框架广泛使用了代理模式,特别是在以下方面:
Spring AOP(面向切面编程):使用代理模式来实现方法拦截和增强,实现例如事务管理、安全检查等横切关注点。
事务管理:Spring通过代理模式管理事务,为方法调用提供声明式事务支持。
Spring Security:在安全框架中,代理用于在方法调用之前和之后执行安全检查。
步骤 1:创建接口
首先定义了一个 Image 接口,用于展示图片。
public interface Image {
void display();
}
步骤 2:实现具体类
创建了 RealImage 类,实现了 Image 接口。这个类代表实际加载的图片。
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName){
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("展示 " + fileName);
}
private void loadFromDisk(String fileName){
System.out.println("加载 " + fileName);
}
}
创建了 ProxyImage 类,也实现了 Image 接口。这个类是 RealImage 对象的代理,负责在需要时加载图片。
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:使用代理对象
ProxyPatternDemo 类演示了如何使用 ProxyImage 来获取和展示 RealImage 对象。
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test_10mb.jpg");
// 图片将从磁盘加载
image.display();
System.out.println("");
// 图片不会从磁盘重新加载
image.display();
}
}
在这个示例中,ProxyImage 充当 RealImage 的代理。当第一次调用 display 方法时,ProxyImage 会创建一个 RealImage 对象并调用其 display 方法。当再次调用 display 方法时,由于 RealImage 对象已经创建,代理将直接使用已加载的对象,而不会再次从磁盘加载图片。
这种方式可以节约资源,特别是在处理大型资源(如大图片)时。通过使用代理模式,只有在实际需要时才加载资源,从而优化了性能并减少了内存占用。
23种设计模式相关代码后续会逐步提交到github上,方便学习,欢迎指点:
代码地址
https://github.com/RuofeiSun/lf-23Pattern