代理设计模式
- 一. 介绍
- 二. 代码示例
- 2.1 定义 CommandExecutor 类
- 2.2 定义 CommandExecutorProxy代理类
- 2.3 模拟客户端
- 2.4 测试结果
- 三. 结论
前言
这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。作者:神的孩子都在歌唱
一. 介绍
官方话语:
代理模式的定义:**为其他对象提供一种代理以控制对这个对象的访问。**在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
我的理解:
代理模式就是需要我们创建一个可以方便两端沟通的桥梁,然后我们可以在这两端之间做一下控制,比如房产中介,比如火车站买票代理点等等 。那么这个定义就非常清晰,当我们想要对提供功能的进行受访控制时,可以使用代理设计模式。
所以代理模式会分为以下三种角色:
(1)抽象(Subject)角色:通过接口或抽象类声明真实角色实现的业务方法。
(2)代理(Proxy)角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
(3)真实(Real Subject)角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
二. 代码示例
具体案例:
假设我们创建了某个CommandExecutor 类,他的作用是可以运行某些linux命令的。这个类一开始是我们程序内部使用,现在需要提供出来给其他客户端程序使用,那么这时候就需要做限制,因为客户端程序可以发出一些危险命令来删除某些系统文件或更改某些您不想要的设置。为了做好限制,我们可以创建一个代理类 CommandExecutorProxy来提供程序的受控访问。关系如下图所示
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 测试结果
可以看到普通用户是没有权限执行rm,管理员就能够执行,这样子comandExecutorProxy类就起到了一个代理的作用
三. 结论
- 代理设计模式的常见用途是访问控制或提供包装器实现以获得更好的性能。Java RMI 包使用代理模式。
使用场景:
-
远程(Remote)代理
本地服务通过网络请求远程服务。为了实现本地到远程的通信,我们需要实现网络通信,处理其中可能的异常。为良好的代码设计和可维护性,我们将网络通信部分隐藏起来,只暴露给本地服务一个接口,通过该接口即可访问远程服务提供的功能,而不必过多关心通信部分的细节。
-
防火墙(Firewall)代理
当你将浏览器配置成使用代理功能时,防火墙就将你的浏览器的请求转给互联网;当互联网返回响应时,代理服务器再把它转给你的浏览器。
-
保护(Protect or Access)代理
控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
参考文章: https://www.digitalocean.com/community/tutorials/decorator-design-pattern-in-java-example#decorator-design-pattern
作者:神的孩子都在歌唱
本人博客:https://blog.csdn.net/weixin_46654114
转载说明:务必注明来源,附带本人博客连接。