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

代理设计模式

    • [一. 介绍](#一. 介绍)
    • [二. 代码示例](#二. 代码示例)
      • [2.1 定义 CommandExecutor 类](#2.1 定义 CommandExecutor 类)
      • [2.2 定义 CommandExecutorProxy代理类](#2.2 定义 CommandExecutorProxy代理类)
      • [2.3 模拟客户端](#2.3 模拟客户端)
      • [2.4 测试结果](#2.4 测试结果)
    • [三. 结论](#三. 结论)

前言

这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。

作者:神的孩子都在歌唱

一. 介绍

官方话语:

代理模式的定义:**为其他对象提供一种代理以控制对这个对象的访问。**在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

我的理解:

代理模式就是需要我们创建一个可以方便两端沟通的桥梁,然后我们可以在这两端之间做一下控制,比如房产中介,比如火车站买票代理点等等 。那么这个定义就非常清晰,当我们想要对提供功能的进行受访控制时,可以使用代理设计模式。

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

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

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

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

二. 代码示例

具体案例:

假设我们创建了某个CommandExecutor 类 ,他的作用是可以运行某些linux命令的 。这个类一开始是我们程序内部 使用,现在需要提供 出来给其他客户端程序 使用,那么这时候就需要做限制,因为客户端程序可以发出一些危险命令删除某些系统文件更改某些您不想要的设置 。为了做好限制,我们可以创建一个代理类 CommandExecutorProxy来提供程序的受控访问。关系如下图所示

2.1 定义 CommandExecutor 类

定义接口

java 复制代码
/**
 * @author chenyunzhi
 */
public interface CommandExecutor {

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

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

java 复制代码
/**
 * @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代理类

java 复制代码
/**
 * @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 模拟客户端

java 复制代码
/**
 * @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 测试结果

可以看到普通用户是没有权限执行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

作者:神的孩子都在歌唱

本人博客:https://blog.csdn.net/weixin_46654114

转载说明:务必注明来源,附带本人博客连接。

相关推荐
Scott9999HH1 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔2 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区6 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai7 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说7 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json