代理模式是一种结构型设计模式,它提供了一个代理对象作为原始对象的替代,以控制对原始对象的访问。代理对象充当了客户端与原始对象之间的中间人,它可以在不改变原始对象的基础上,为原始对象添加一些额外的功能。
在这篇文章中,我们将详细解读代理模式(Proxy Pattern),并通过实际的编程案例来加深对其的理解,代理模式是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问,这种模式主要分为静态代理和动态代理两种类型,本文将分别介绍这两种代理模式的特点、应用场景以及优缺点。
我们来了解一下什么是代理模式,代理模式是一种结构型设计模式,它通过为其他对象提供一种代理以控制对这个对象的访问,这种模式主要分为静态代理和动态代理两种类型,静态代理是在编译时就确定了代理类和被代理类的关系,而动态代理是在运行时动态生成代理类。
1、静态代理
静态代理是在编译时就确定了代理类和被代理类的关系,通常情况下,静态代理类实现一个接口,被代理类实现了另一个接口,静态代理类持有被代理类的实例,并通过调用被代理类的方法来实现对被代理类的访问控制。
下面我们通过一个简单的示例来说明静态代理的使用:
// 定义一个接口 interface Subject { void request(); } // 实现接口的具体类 class RealSubject implements Subject { @Override public void request() { System.out.println("RealSubject: Handling request."); } } // 静态代理类 class StaticProxy implements Subject { private RealSubject realSubject; public static void main(String[] args) { StaticProxy proxy = new StaticProxy(); proxy.setRealSubject(new RealSubject()); proxy.request(); // 输出:RealSubject: Handling request. } @Override public void request() { if (realSubject == null) { System.out.println("StaticProxy: Creating a new RealSubject."); realSubject = new RealSubject(); } System.out.println("StaticProxy: Forwarding request to RealSubject."); realSubject.request(); } }
2、动态代理
动态代理是在运行时动态生成代理类,Java提供了java.lang.reflect
包下的Proxy
类和InvocationHandler
接口来实现动态代理,动态代理的主要优点是它可以在不修改原始类的情况下实现对原始类的访问控制。
下面我们通过一个简单的示例来说明动态代理的使用:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 实现接口的具体类 class RealSubject implements Subject { @Override public void request() { System.out.println("RealSubject: Handling request."); } } // 实现InvocationHandler接口的动态代理类 class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("DynamicProxy: Before invoking the target method."); Object result = method.invoke(target, args); System.out.println("DynamicProxy: After invoking the target method."); return result; } } public class Main { public static void main(String[] args) { RealSubject realSubject = new RealSubject(); DynamicProxy dynamicProxy = new DynamicProxy(realSubject); Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), dynamicProxy); proxy.request(); // 输出:DynamicProxy: Before invoking the target method., RealSubject: Handling request., DynamicProxy: After invoking the target method. } }
通过以上两个示例,我们可以看到代理模式在不同场景下的应用,代理模式可以帮助我们在不修改原始类的基础上实现对原始类的访问控制,从而提高代码的可扩展性和可维护性。