神的孩子都在歌唱

神的孩子都在歌唱

一. 介绍

官方话语:

我的理解:

所以代理模式会分为以下三种角色:

(1)抽象(Subject)角色:通过接口或抽象类声明真实角色实现的业务方法。

(2)代理(Proxy)角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

(3)真实(Real Subject)角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

二. 代码示例

具体案例:

结构设计模式 - 代理设计模式 - JAVA-LMLPHP

2.1 定义 CommandExecutor 类

定义接口

/**
 * @author chenyunzhi
 */
public interface CommandExecutor {

    /**
     * 执行命令
     * @param cmd 命令
     */
    void exec(String cmd);
}

实现接口,这里是编写我们内部使用的类

/**
 * @author chenyunzhi
 * @date 2024/5/31 14:25
 * @Description
 */
public class CommandExecutorImpl implements CommandExecutor{
    @Override
    public void exec(String cmd) {
        System.out.println("执行了" + cmd);
    }
}

2.2 定义 CommandExecutorProxy代理类

/**
 * @author chenyunzhi
 * @date 2024/5/31 14:28
 * @Description
 */
public class CommandExecutorProxy implements CommandExecutor{

    private boolean admin;
    private final CommandExecutor commandExecutor;
    
    public CommandExecutorProxy() {
        commandExecutor = new CommandExecutorImpl();
    }
    
    public CommandExecutorProxy(String user, String password) {
        // 需要输入正确账号密码才能获得管理员权限
        if ("admin".equals(user)  && "123456".equals(password)) {
            admin = true;
        }
        commandExecutor = new CommandExecutorImpl();
    }
    @Override
    public void exec(String cmd) {
        if (!admin) {
            if (cmd.startsWith("rm")) {
                System.out.println(cmd + "没有权限执行");
                return;
            }
        }
        commandExecutor.exec(cmd);
    }
}

2.3 模拟客户端

/**
 * @author chenyunzhi
 * @date 2024/5/31 14:41
 * @Description  客户端
 */
public class ProxyDesignPatternTest {
    public static void main(String[] args) {

        System.out.println("-----------普通用户执行命令-----------");
        CommandExecutorProxy commandExecutorProxy = new CommandExecutorProxy();

        commandExecutorProxy.exec("ls");

        commandExecutorProxy.exec("rm");

        System.out.println("-------------管理员执行命令-----------");

        commandExecutorProxy = new CommandExecutorProxy("admin", "123456");

        commandExecutorProxy.exec("ls");

        commandExecutorProxy.exec("rm");

    }

}

2.4 测试结果

结构设计模式 - 代理设计模式 - JAVA-LMLPHP

可以看到普通用户是没有权限执行rm,管理员就能够执行,这样子comandExecutorProxy类就起到了一个代理的作用

三. 结论

  1. 代理设计模式的常见用途是访问控制或提供包装器实现以获得更好的性能。Java RMI 包使用代理模式。

使用场景:

  1. 远程(Remote)代理

    本地服务通过网络请求远程服务。为了实现本地到远程的通信,我们需要实现网络通信,处理其中可能的异常。为良好的代码设计和可维护性,我们将网络通信部分隐藏起来,只暴露给本地服务一个接口,通过该接口即可访问远程服务提供的功能,而不必过多关心通信部分的细节。

  2. 防火墙(Firewall)代理

    当你将浏览器配置成使用代理功能时,防火墙就将你的浏览器的请求转给互联网;当互联网返回响应时,代理服务器再把它转给你的浏览器。

  3. 保护(Protect or Access)代理

    控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。

参考文章: https://www.digitalocean.com/community/tutorials/decorator-design-pattern-in-java-example#decorator-design-pattern

06-05 16:00