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 对象的访问。根据员工的角色级别决定是否授予互联网访问权限,从而保护了实际对象并在必要时才创建它。
 
          
          
         