代理模式是一种常用的软件设计模式,它为其他对象提供一种代理以控制对这个对象的访问。这种模式创建具有原始对象相同接口的对象,从而使代理对象在访问者和目标对象之间作为一个中介。
代理模式的概念:
- 目标接口(Subject):一个接口,既被真实主题实现,也被代理类实现,这样代理就可以用来替代真实主题。
- 真实主题(Real Subject):实现目标接口的类,定义代理所代表的真实对象。
- 代理类(Proxy):同样实现目标接口,包含一个引用使得代理可以访问实体,并提供一个与目标接口相同的接口,这样代理就可以替代实体。
优点:
- 封装性:代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度。
- 增强功能:代理类不仅仅能代表真实主题,还可以在调用真实主题的方法前后添加其他功能,比如权限检查、缓存、日志等。
- 智能化:通过代理,可以在不修改目标对象代码的情况下,对目标功能进行扩展。
缺点:
- 可能会造成系统设计变复杂:引入代理对象后,会有更多的代码需要编写,系统结构复杂化。
- 响应时间变慢:在访问真实主题之前,可能需要执行一些前置检查。特别是在网络请求中,增加代理层会导致请求速度变慢。
- 实现复杂:尤其是动态代理的实现较为复杂。
Java代码示例(静态代理):
java复制代码
// 定义接口
interface Image {
void display();
}
// 真实对象
class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
private void loadFromDisk(String fileName) {
System.out.println("Loading " + fileName);
}
}
// 代理对象
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();
}
}
// 客户端
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test_image.jpg");
// 图像将从磁盘加载
image.display();
// 图像不需要从磁盘加载
image.display();
}
}
在这个例子中,ProxyImage充当代理角色,控制对RealImage对象的访问,并在必要时才创建RealImage对象并加载图片。这种延迟加载是代理模式的一个典型应用场景。