Design Patterns教程-代理模式

代理模式表示 “提供对原始对象的控制访问”。
代理模式的核心是通过代理对象代表另一个对象进行操作,从而隐藏原始对象的信息,进行按需加载等操作。
代理模式也称为 Surrogate 或 Placeholder。
RMI API 使用了代理设计模式。Stub 和 Skeleton 是 RMI 中使用的两个代理对象。
代理模式的优点
- 它为原始对象提供了保护,使其免受外部世界的干扰。
代理模式的使用
适用于以下情况:
- 虚代理(Virtual Proxy) 场景:考虑一个需要多次数据库调用以提取大尺寸图像的情况。这是一个昂贵的操作,因此可以使用代理模式创建多个代理,并指向占用大量内存的对象进行进一步处理。真正的对象仅在客户端首次请求/访问对象时创建,之后可以引用代理来重用对象,从而避免对象重复,节省内存。
- 保护代理(Protective Proxy) 场景:充当授权层,以验证实际用户是否有权限访问适当的内容。例如,在办公室中提供限制互联网访问的代理服务器。只有有效的网站和内容才会被允许,其他内容将被阻止。
- 远程代理(Remote Proxy) 场景:远程代理可以被视为 RPC 调用中的存根。远程代理提供了不同地址位置上的对象的本地表示。另一个示例是为远程资源(如 Web 服务或 REST 资源)提供接口。
- 智能代理(Smart Proxy) 场景:智能代理通过在访问对象时插入特定操作提供额外的安全层。例如,在访问实际对象之前检查其是否已锁定,以便其他对象无法更改它。
代理模式示例
让我们通过上面的 UML 图来理解代理设计模式的示例。
代理模式的 UML:
实现上述 UML:
步骤 1
创建一个 OfficeInternetAccess 接口。
public interface OfficeInternetAccess {
public void grantInternetAccess();
}
步骤 2
创建一个实现 OfficeInternetAccess 接口的 RealInternetAccess 类,用于向特定员工授予权限。
文件:RealInternetAccess.java
public class RealInternetAccess implements OfficeInternetAccess {
private String employeeName;
public RealInternetAccess(String empName) {
this.employeeName = empName;
}
@Override
public void grantInternetAccess() {
System.out.println("Internet Access granted for employee: " + employeeName);
}
}
步骤 3
创建一个实现 OfficeInternetAccess 接口的 ProxyInternetAccess 类,用于提供 RealInternetAccess 类的对象。
文件:ProxyInternetAccess.java
public class ProxyInternetAccess implements OfficeInternetAccess {
private String employeeName;
private RealInternetAccess realaccess;
public ProxyInternetAccess(String employeeName) {
this.employeeName = employeeName;
}
@Override
public void grantInternetAccess() {
if (getRole(employeeName) > 4) {
realaccess = new RealInternetAccess(employeeName);
realaccess.grantInternetAccess();
} else {
System.out.println("No Internet access granted. Your job level is below 5");
}
}
public int getRole(String emplName) {
// 根据姓名和职位从数据库中检查角色
// 返回工作级别或职位。
return 9;
}
}
步骤 4
创建一个 ProxyPatternClient 类,实际访问互联网。
文件:ProxyPatternClient.java
public class ProxyPatternClient {
public static void main(String[] args) {
OfficeInternetAccess access = new ProxyInternetAccess("Ashwani Rajput");
access.grantInternetAccess();
}
}
输出
Internet Access granted for employee: Ashwani Rajput
在上述示例中,我们通过 ProxyInternetAccess
类控制对 RealInternetAccess
对象的访问。根据员工的角色级别决定是否授予互联网访问权限,从而保护了实际对象并在必要时才创建它。