代理模式表示 “提供对原始对象的控制访问”

代理模式的核心是通过代理对象代表另一个对象进行操作,从而隐藏原始对象的信息,进行按需加载等操作。

代理模式也称为 Surrogate 或 Placeholder

RMI API 使用了代理设计模式。Stub 和 Skeleton 是 RMI 中使用的两个代理对象。

代理模式的优点

  • 它为原始对象提供了保护,使其免受外部世界的干扰。

代理模式的使用

适用于以下情况:

  • 虚代理(Virtual Proxy) 场景:考虑一个需要多次数据库调用以提取大尺寸图像的情况。这是一个昂贵的操作,因此可以使用代理模式创建多个代理,并指向占用大量内存的对象进行进一步处理。真正的对象仅在客户端首次请求/访问对象时创建,之后可以引用代理来重用对象,从而避免对象重复,节省内存。
  • 保护代理(Protective Proxy) 场景:充当授权层,以验证实际用户是否有权限访问适当的内容。例如,在办公室中提供限制互联网访问的代理服务器。只有有效的网站和内容才会被允许,其他内容将被阻止。
  • 远程代理(Remote Proxy) 场景:远程代理可以被视为 RPC 调用中的存根。远程代理提供了不同地址位置上的对象的本地表示。另一个示例是为远程资源(如 Web 服务或 REST 资源)提供接口。
  • 智能代理(Smart Proxy) 场景:智能代理通过在访问对象时插入特定操作提供额外的安全层。例如,在访问实际对象之前检查其是否已锁定,以便其他对象无法更改它。

代理模式示例

让我们通过上面的 UML 图来理解代理设计模式的示例。

代理模式的 UML:

7-1.jpg

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

标签: Design Patterns, Design Patterns教程, 设计模式, 软件设计, 结构型模式, 行为型模式, 单例模式, 工厂模式, 观察者模式, 中介者模式, 访问者模式