推荐答案
代理模式(Proxy Pattern)是一种结构型设计模式,它允许你提供一个代理对象来控制对另一个对象的访问。代理对象通常会在客户端和目标对象之间起到中介作用,从而可以在不改变目标对象的情况下,增加额外的功能或控制访问。
在 Java 中,代理模式通常分为两种类型:
- 静态代理:代理类在编译时就已经确定,通常需要手动编写代理类。
- 动态代理:代理类在运行时动态生成,通常使用 Java 的反射机制来实现。
本题详细解读
1. 静态代理
静态代理的实现方式是通过手动编写一个代理类,该类实现了与目标对象相同的接口,并在代理类中调用目标对象的方法。静态代理的优点是简单直观,缺点是每个代理类只能代理一个接口,如果需要代理多个接口,则需要编写多个代理类。
// www.javascriptcn.com code example
// 目标接口
interface Subject {
void request();
}
// 目标类
class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 代理类
class Proxy implements Subject {
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
public void request() {
System.out.println("Proxy: Pre-processing.");
realSubject.request();
System.out.println("Proxy: Post-processing.");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Proxy proxy = new Proxy(realSubject);
proxy.request();
}
}2. 动态代理
动态代理是通过 Java 的 java.lang.reflect.Proxy 类在运行时动态生成代理对象。动态代理不需要手动编写代理类,而是通过实现 InvocationHandler 接口来处理代理对象的调用。
// www.javascriptcn.com code example
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 目标接口
interface Subject {
void request();
}
// 目标类
class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 动态代理处理器
class DynamicProxyHandler implements InvocationHandler {
private Object target;
public DynamicProxyHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("DynamicProxy: Pre-processing.");
Object result = method.invoke(target, args);
System.out.println("DynamicProxy: Post-processing.");
return result;
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Subject proxy = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
new DynamicProxyHandler(realSubject)
);
proxy.request();
}
}3. 代理模式的应用场景
- 远程代理:为远程对象提供一个本地代理,隐藏远程调用的复杂性。
- 虚拟代理:延迟创建开销较大的对象,直到真正需要时才创建。
- 保护代理:控制对敏感对象的访问,增加权限检查。
- 智能引用:在访问对象时执行额外的操作,如记录日志、缓存等。
4. 代理模式的优缺点
优点:
- 可以在不修改目标对象的情况下,增加额外的功能。
- 代理模式可以实现对目标对象的访问控制。
缺点:
- 静态代理需要为每个目标对象编写代理类,增加了代码的复杂性。
- 动态代理虽然灵活,但使用反射机制可能会带来性能开销。