深入理解(Proxy)代理设计模式一 概念和基本实现
所谓的代理就是用户不能直接接触到真实的对象的,而是通过一个代理对象来进行间接的访问。
为什么要这样做?一个关键字就是”控制“。
来看看在GOF一书中是怎么定义的:
1.意图:
为其它对象提供一种代理以控制对这个对象的访问。
2.别名
Surrogate 这个单词也是代理的意思,基本是同义词
3.动机
举一个最常听说的例子,就是网络代理,包括游戏加速器,梯子等等。例如一个跨国的游戏,不同国家的玩家可以同一个游戏里面游玩,但这里涉及一个网络延迟的问题。有些网络节点非常的慢,这时候就需要所谓的加速器帮我们连接最快的节点来解决网络延迟问题。对于用户来说,网络变得流畅了。其实这个例子是不太恰当的,因为加速器这种东西不是还要用户自己下载设置?如果这个加速器是游戏自带的呢?用户不需要做任何操作。设置模式所说的当然是后者这种自带的代理。更确切的说,就是代理具体的程序类。
其实代理模式最有用最强大的地方就是增强被代理类的功能。
在执行一个方法的时候,有没有办法在执行方法之前做一些事情,在执行方法之后再做一些事情呢?代理设计模式就可以用来实现这种功能。最典型的就是JDK提供的动态代理功能,还要基于动态代理功能的AspectJ AOP框架。但这些都是通过反射机制来实现的。我们先要讨论的是最原始的不用反射机制实现的代理设计模式。然后再讨论动态代理的实现方式。
结构:
代理类的UML结构非常的简单。通过这个图可以非常直观的看到代理设计模式的结构
我们直接看下面的UML结构图,在接口中有一个request方法。RealSubject是我们的真实类,实现了request方法。而我们的代理类,明显比被代理的类多了几个方法,而且还有对RealSubject的引用。
复制粘贴下面的代码到IDE,并且运行一下,主要实现的功能就是在调用request方法之前和之后执行一些操作。
public interface Subject {
void request();
}
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("From real subject");
}
}
public class ProxySubject implements Subject {
RealSubject realSubject;
@Override
public void request() {
//额外功能1
preRequest();
if (realSubject == null) {
realSubject = new RealSubject();
}
//真实关联的部分
realSubject.request();
//额外功能2
afterRequest();
}
/**
* 这个方法是自定义的,根据业务想写什么都行,执行时机也可以随便,不过要换个名字而已。
*/
public void preRequest() {
System.out.println("before...");
}
/**
* 含义同preRequest方法
*/
public void afterRequest() {
System.out.println("after...");
}
}
public class Client {
public static void main(String[] args) {
Subject subject=new ProxySubject();
subject.request();
}
}
before...
From real subject
after...
这就是最简单的代理模式的实现。看起来是代理,其实更像是挟持和拦截。其实代理模式可以实现类似权限管理的功能,这就是真正的拦截了。
在GOF书中给出了四种不同的代理,而像拦截这样的功能属于保护代理,其它代理后面会继续讲到。
下一篇 我们讲Java的动态代理。
https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html
https://blog.csdn.net/weixin_40763897/article/details/88661822
动态代理原理
https://blog.csdn.net/riemann_/article/details/86777505