结构型模式(二):代理模式
- 3.代理模式(Proxy)
- 3.1 主要特点
- 3.2 组成部分
- 3.3 示例代码
- 3.3.1 Subject 接口
- 3.3.2 RealSubject 实际对象
- 3.3.3 Proxy 代理对象
- 3.3.4 客户端代码
- 3.3.5 运行结果
- 3.4 总结
3.代理模式(Proxy)
代理模式(Proxy Pattern
)是一种结构型设计模式,它允许你提供一个代理对象来控制对某个对象的访问。代理对象可以执行一些额外的操作,如 权限检查、日志记录、延迟初始化 等,然后再将请求转发给实际的对象。
3.1 主要特点
- 控制访问:代理对象可以控制对实际对象的访问,增加额外的功能。
- 透明性:客户端代码可以通过代理对象来访问实际对象,而不需要知道实际对象的存在。
- 灵活性:可以在不修改客户端代码的情况下,动态地添加或修改代理对象的行为。
3.2 组成部分
-
Subject
(主题接口)- 定义了实际对象和代理对象 共同的接口,使得客户端可以使用相同的接口来访问实际对象和代理对象。
-
RealSubject
(实际对象)- 实现了主题接口,提供了实际的业务逻辑。
-
Proxy
(代理对象)- 也实现了主题接口,持有一个实际对象的引用。
- 在调用实际对象的方法前后,可以执行额外的操作。
3.3 示例代码
假设我们有一个 Image 接口,用于显示图片。为了提高性能,我们使用代理模式来实现图片的延迟加载。
3.3.1 Subject 接口
// Subject 接口
interface Image {
void display();
}
-
Image
接口定义了display
方法,表示显示图片的行为。
3.3.2 RealSubject 实际对象
// RealSubject 实际对象
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk();
}
@Override
public void display() {
System.out.println("Displaying " + filename);
}
private void loadFromDisk() {
System.out.println("Loading " + filename);
}
}
-
RealImage
类实现了Image
接口,提供了实际的图片 加载 和 显示 功能。 - 在构造方法中,图片被加载到内存中。
3.3.3 Proxy 代理对象
// Proxy 代理对象
class ImageProxy implements Image {
private RealImage realImage;
private String filename;
public ImageProxy(String filename) {
this.filename = filename;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(filename);
}
realImage.display();
}
}
- ImageProxy 类也实现了 Image 接口,持有一个 RealImage 对象的引用。
- 在
display
方法中,如果realImage
为空,则创建 RealImage 对象并加载图片;否则,直接调用realImage
的display
方法。
3.3.4 客户端代码
// 客户端代码
public class ProxyPatternExample {
public static void main(String[] args) {
Image image1 = new ImageProxy("image1.jpg");
Image image2 = new ImageProxy("image2.jpg");
image1.display(); // 第一次调用,会加载图片
image1.display(); // 第二次调用,不会重新加载图片
image2.display(); // 第一次调用,会加载图片
image2.display(); // 第二次调用,不会重新加载图片
}
}
- 客户端代码通过 ImageProxy 对象来访问图片。
- 第一次调用
display
方法时,图片会被加载到内存中;后续调用时,图片已经加载,不会再重新加载。
3.3.5 运行结果
Loading image1.jpg
Displaying image1.jpg
Displaying image1.jpg
Loading image2.jpg
Displaying image2.jpg
Displaying image2.jpg
3.4 总结
- 优点
- 延迟初始化:只有在需要时才加载和初始化实际对象,提高了性能。
- 控制访问:可以在代理对象中添加额外的逻辑,如权限检查、日志记录等。
- 透明性:客户端代码可以通过代理对象访问实际对象,而不需要知道实际对象的存在。
- 缺点
- 复杂性:增加了额外的类和对象,可能会使代码变得复杂。
- 性能开销:每次调用方法时都需要通过代理对象,可能会有额外的性能开销。
通过代理模式,可以在不修改客户端代码的情况下,动态地添加或修改对象的行为,提高系统的灵活性和可维护性。