概念理解
在程序中,不能或不想直接访问目标对象,这时创建一个代理对象作为访问对象和目标对象之间的中介。代理模式的特点就是控制对象的访问。
生活中常见的例子就是翻墙用的各种梯子
使用场景
- 远程代理
- 虚拟代理
- 缓冲代理
- 安全代理
- 智能指引
- 延迟加载
结构
Subject(抽象主题角色): 定义代理类和真实主题的公共对外方法,也是代理类代理真实主题的方法。
RealSubject(真实主题角色): 真正实现业务逻辑的类。
Proxy(代理主题角色): 用来代理和封装真实主题
实例
静态代理
Subject
public interface Subject {
void request();
}
RealSubject
public class RealSubject implements Subject{
@Override
public void request() {
System.out.println("do something");
}
}
ProxySubject
public class ProxySubject implements Subject {
private Subject subject;
@Override
public void request() {
if (subject == null) {
subject = new RealSubject();
}
this.preRequest();
subject.request();
this.postRequest();
}
private void preRequest(){
System.out.println("预处理工作...");
}
private void postRequest(){
System.out.println("后续工作...");
}
}
Client
public class Client {
public static void main(String[] args) {
Subject subject = new ProxySubject();
subject.request();
}
}
预处理工作...
do something
后续工作...
动态代理写法
Subjec
public interface Subjec {
void request();
}
RealSubject
public class RealSubject implements Subjec{
@Override
public void request() {
System.out.println("do something...");
}
}
ProxySubject
public class ProxySubject implements InvocationHandler {
private Object object;
public ProxySubject(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("预处理...");
method.invoke(object, args);
System.out.println("后续处理...");
return null;
}
}
Client
public class Client {
public static void main(String[] args) {
// 实例化目标对象
RealSubject realSubject = new RealSubject();
// 实例化调用处理类
InvocationHandler handler = new ProxySubject(realSubject);
// 创建代理(通过Proxy直接创建动态代理实例)
Subjec subjec = (Subjec) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler);
subjec.request();
}
}
预处理...
do something...
后续处理...
代理模式的优缺点
代理模式的主要优点有:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;
其主要缺点是:
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
- 增加了系统的复杂度;