常用设计模式7:代理模式(Java)
代理模式(Proxy Pattern)
1. 简介
代理模式是一种结构型设计模式,它允许提供一个代替品或占位符来控制对原对象的访问。代理对象可以在客户端和目标对象之间起到中介的作用,并且可以添加额外的功能。
2. 为什么使用代理模式?
- 控制访问:代理可以控制对原对象的访问,并可以在访问对象之前或之后执行一些额外的操作。
- 延迟加载:代理可以推迟昂贵对象的创建或加载。
- 添加功能:代理可以在不修改原对象的情况下,给原对象添加额外的功能。
- 远程代理:可以用于表示一个远程系统中的对象。
- 保护代理:控制对原始对象的访问权限。
3. 代理模式的结构
代理模式主要包含以下角色:
- Subject:抽象主题,定义了RealSubject和Proxy的共用接口。
- RealSubject:真实主题,定义了Proxy所代表的真实实体。
- Proxy:代理类,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口。
4. Java 实现示例
下面通过一个简单的图片加载系统来说明代理模式:
4.1 定义抽象主题
public interface Image {
void display();
}
4.2 实现真实主题
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("Loading " + fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
}
4.3 实现代理类
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();
}
}
4.4 客户端代码
public class Client {
public static void main(String[] args) {
Image image1 = new ProxyImage("photo1.jpg");
Image image2 = new ProxyImage("photo2.jpg");
// 图片将从磁盘加载
image1.display();
// 图片不需要从磁盘加载
image1.display();
// 图片将从磁盘加载
image2.display();
}
}
5. 代理模式的优缺点
优点:
- 可以在客户端毫无察觉的情况下控制服务对象。
- 如果客户端对服务对象的生命周期没有特殊要求,可以对生命周期进行管理。
- 即使服务对象还未准备好或不存在,代理也可以正常工作。
- 开闭原则。可以在不对服务或客户端做出修改的情况下创建新代理。
缺点:
- 代码可能会变得更加复杂,因为需要新增许多类。
- 服务响应可能会延迟。
6. 适用场景
- 延迟初始化(虚拟代理):如果有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源。
- 访问控制(保护代理):如果只希望特定客户端使用服务对象,这里的对象可以是操作系统中非常重要的部分。
- 本地执行远程服务(远程代理):适用于服务对象位于远程服务器上的情形。
- 记录日志请求(日志记录代理):需要保存对服务对象的请求历史记录时。
- 缓存请求结果(缓存代理):需要缓存客户请求结果并对缓存生命周期进行管理时。
7. 总结
代理模式是一种强大而灵活的设计模式,它允许控制对对象的访问,添加额外的功能,或者延迟对象的创建和初始化。通过使用代理,可以在不修改原始代码的情况下增强修改对象的行为。然而,过度使用代理可能会使系统变得复杂,因此在使用时需要权衡利弊。代理模式在很多场景下都非常有用,比如延迟加载、访问控制、日志记录等,它是 Java 开发中常用的设计模式之一。

浙公网安备 33010602011771号